SQL查询在EXPLAIN上甚至“使用索引”也太慢了

时间:2012-04-17 17:08:09

标签: mysql sql performance

我正在尝试获取用户的所有订阅者

我的疑问:

SELECT
    COUNT(sub.id) as ids
FROM
    subscribers as sub
WHERE
    suid=541839243781

EXPLAIN打印:

╔════╦═════════════╦═══════╦══════╦═══════════════╦═════╦═════════╦═══════╦═══════╦═════════════╗
║ id ║ select_type ║ table ║ type ║ possible_keys ║ key ║ key_len ║  ref  ║ rows  ║    Extra    ║
╠════╬═════════════╬═══════╬══════╬═══════════════╬═════╬═════════╬═══════╬═══════╬═════════════╣
║  1 ║ SIMPLE      ║ sub   ║ ref  ║ i3            ║ i3  ║       8 ║ const ║ 47890 ║ Using index ║
╚════╩═════════════╩═══════╩══════╩═══════════════╩═════╩═════════╩═══════╩═══════╩═════════════╝

因此,目前我获得的总计数大约为48k,加载0.0333需要加载...如果这最多可达1m5m怎么办? ?加载可能需要很长时间......

订阅者表上的索引是:

╔═════════════╦════════════╦═══════════════════╦══════════════╦═════════════╦═══════════╦═════════════╦══════════╦════════╦══════╦════════════╦═════════╗
║    Table    ║ Non_unique ║     Key_name      ║ Seq_in_index ║ Column_name ║ Collation ║ Cardinality ║ Sub_part ║ Packed ║ Null ║ Index_type ║ Comment ║
╠═════════════╬════════════╬═══════════════════╬══════════════╬═════════════╬═══════════╬═════════════╬══════════╬════════╬══════╬════════════╬═════════╣
║ subscribers ║          0 ║ PRIMARY           ║            1 ║ id          ║ A         ║       60251 ║ NULL     ║ NULL   ║      ║ BTREE      ║         ║
║ subscribers ║          1 ║ total_subscribers ║            1 ║ id          ║ A         ║       60251 ║ NULL     ║ NULL   ║      ║ BTREE      ║         ║
║ subscribers ║          1 ║ total_subscribers ║            2 ║ suid        ║ A         ║       60251 ║ NULL     ║ NULL   ║      ║ BTREE      ║         ║
║ subscribers ║          1 ║ i3                ║            1 ║ suid        ║ A         ║        6025 ║ NULL     ║ NULL   ║      ║ BTREE      ║         ║
║ subscribers ║          1 ║ i3                ║            2 ║ uid         ║ A         ║       60251 ║ NULL     ║ NULL   ║      ║ BTREE      ║         ║
║ subscribers ║          1 ║ i3                ║            3 ║ id          ║ A         ║       60251 ║ NULL     ║ NULL   ║      ║ BTREE      ║         ║
╚═════════════╩════════════╩═══════════════════╩══════════════╩═════════════╩═══════════╩═════════════╩══════════╩════════╩══════╩════════════╩═════════╝

那么我怎样才能使这个查询更有效率?

3 个答案:

答案 0 :(得分:1)

你可能不会。

那就是说,我希望COUNT操作必须与行数成线性比例。您可能会发现100万行需要0.12秒而不是0.0333秒。

如果它确实成为问题,您可以使用预计算和缓存来解决此问题。例如,您可能有一个每小时的工作来计算计数并将它们存储在表中。你的计数可能会长达一个小时过时,但检索它们会快得多。

答案 1 :(得分:1)

id是否允许NULL值?如果没有,请更改为SELECT COUNT(*),引擎将能够单独从索引回答查询,而不参考表数据。这应该加快速度,并且根据MySQL存储和检索基数统计数据的方式,可以使查询立即生效。

答案 2 :(得分:0)

您可以将sys.tables加入sys.partitions。行统计数据存储在那里。

错误:这适用于MS SQL Server,抱歉应该提到的。