【问题标题】:MariaDB - Indexing not improving performance on char(255) fieldMariaDB - 索引未提高 char(255) 字段的性能
【发布时间】:2021-08-16 09:54:00
【问题描述】:

我正在尝试在一个有 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           |

【问题讨论】:

    标签: mysql database indexing mariadb database-performance


    【解决方案1】:

    优化器注意到该索引列几乎没有不同的值。所以它意识到需要很多行。所以它决定简单地翻阅表格而不用担心索引。 (使用索引会涉及在索引的 BTree 和数据的 BTree 之间来回跳动很多。)

    因此,您通过指出LIMIT 100 来反击。这是一个有效的问题。唉,这指出了优化器的一个缺陷。

    它被撕裂了

    • 忽略索引,如果需要扫描整个表,这可能是最佳选择。注意:如果您需要的 100 行恰好位于表的末尾,就会发生这种情况。
    • 使用索引,但要支付额外的开销。在这里它没有意识到 100 远小于 1M,因此提高了索引通常是最佳方法的可能性。

    让我们尝试欺骗它...删除该索引并添加另一个索引。这次放了2列:

     (dim_agg_strategy, xx)
    

    xx 是其他列。

    (让我知道这个技巧是否适合你。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-28
      • 2014-11-25
      • 2021-04-16
      • 2017-09-14
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      相关资源
      最近更新 更多