如何解决MariaDB - 索引没有提高 char(255) 字段的性能
我正在尝试在一个只有 100 万条记录的表上执行此 SQL 查询:
SELECT * FROM enty_score limit 100;
它给了我大约 600 毫秒的结果
在字段 `dim_agg_strategy` char(255) DEFAULT NULL
上添加 where 子句后,执行时间为 40 秒:
SELECT * FROM enty_score WHERE dim_agg_strategy='COMPOSITE_AVERAGE_LAKE' limit 100;
我已经尝试创建一个索引,但没有任何改进,执行相同的查询仍然需要 40 秒:
ALTER TABLE `enty_score` ADD INDEX `dim_agg_strategy_index` (`dim_agg_strategy`);
SELECT INDEX_NAME,COLUMN_NAME,CARDINALITY,NULLABLE,INDEX_TYPE
FROM information_schema.statistics where INDEX_NAME = 'dim_agg_strategy_index';
INDEX_NAME |COLUMN_NAME |CARDINALITY|NULLABLE|INDEX_TYPE|
----------------------+----------------+-----------+--------+----------+
dim_agg_strategy_index|dim_agg_strategy| 586|YES |BTREE |
更多信息,我放在 where 子句中的这一列只包含 6 个不同的值:
select distinct dim_agg_strategy from enty_score;
dim_agg_strategy |
-------------------------+
COMPOSITE_AVERAGE |
COMPOSITE_AVERAGE_ALL |
COMPOSITE_AVERAGE_LAKE |
COMPOSITE_AVERAGE_NONLAKE|
NORMALISED_AVERAGE |
SIMPLE_AVERAGE |
解决方法
优化器注意到该索引列几乎没有不同的值。所以它意识到需要很多行。所以它决定简单地翻阅表格,而不用打扰索引。 (使用索引会涉及在索引的 BTree 和数据的 BTree 之间来回跳动很多。)
因此,您通过指出 LIMIT 100
来反击。这是一个有效的问题。唉,这指出了优化器的一个缺陷。
夹在中间
- 忽略索引,如果需要扫描整个表,这可能是最佳选择。注意:如果您需要的 100 行恰好位于表格的末尾,就会发生这种情况。
- 使用索引,但要支付额外的开销。这里没有意识到 100 远小于 1M,因此提高了指数通常是最佳方法的几率。
让我们试着欺骗它...删除该索引并添加另一个索引。这次放了2列:
(dim_agg_strategy,xx)
其中 xx
是其他列。
(如果这个技巧对你有用,请告诉我。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。