在 MySQL / MariaDB 中,我有一个带有固定长度行的表(没有 VARCHAR、TEXT 等)
CREATE TABLE trigram (
id BIGINT(20) NOT NULL,
trigram CHAR(3) NOT NULL COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (trigram, id) USING BTREE,
INDEX id (id) USING BTREE
)
COLLATE='utf8mb4_general_ci' ENGINE=InnoDB ROW_FORMAT=COMPACT;
该表有数十兆行,并获取这种形式的生产查询
SELECT id FROM trigram
WHERE trigram IN ('dba', 'ba.', 'a.s', '.st', 'sta', 'tac', 'ack')
GROUP BY ID HAVING COUNT(*) = 7
以及插入和DELETE FROM trigram WHERE id = 12345
维护查询。索引适合表的查询模式。
该表是穷人的卦索引。(这个可怜的人无法升级到 postgreSQL 并使用其内置的 trigram 索引,叹息。)示例查询查找id
其中包含“dba.stack”字符串的 s。content_column LIKE '%dba.stack%'
它比建立三卦表要快得多。
编辑: “更好”是什么意思?更快、更可靠、生产中缓冲池刷新更少、非 DBA 用户的维护负担更少。
问题:我应该使用 ROW_FORMAT=COMPACT 定义这个固定长度行表吗?或者需要 DYNAMIC 吗?我注意到 COMPACT 占用的磁盘空间要少得多。
问题:还有其他建议或需要担心的性能问题吗?
我的用户(WordPress.org 软件用户)大部分使用 MariaDB 10.3+,但也有一些使用 MySQL 8,还有一些使用 MySQL 5.7-。我不需要支持 Antelope 或 MyISAM 遗留的东西。
另一个编辑:
我的IN()
查询对表中包含 180K 行的测试数据集进行范围扫描。JOIN
答案中建议的 UNION 表执行嵌套循环。范围扫描花费的时间更少。在 MariaDB 10.11、MySQL 8 和 MySQL 5.7 上正确。物有所值。看起来跳过扫描优化效果很好。