2012-04-17 84 views
0

我想获得一个用户的所有用户SQL查询太慢甚至 “使用索引” 解释

我的查询:

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  ║   ║ 
╚═════════════╩════════════╩═══════════════════╩══════════════╩═════════════╩═══════════╩═════════════╩══════════╩════════╩══════╩════════════╩═════════╝ 

所以我怎样才能让这个查询更有效?

+0

如果我正确读取数据,则没有“suid”列的专用索引。 “suid”列值是全球唯一还是仅针对每个订阅者? – 2012-04-17 17:27:12

+0

已编辑的索引,忘记了一个索引 – fxuser 2012-04-17 17:33:00

回答

1

你可能不能。

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

如果它真的成为问题,您可能可以使用预计算和缓存来解决此问题。例如,您可能有一项每小时工作计算计数并将其存储在一张桌子上。你的计数可能会过去一小时,但检索它们会快得多。

0

您可以将sys.tables加入sys.partitions。行统计信息存储在表中。

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

1

id是否允许NULL值?如果没有,则更改为SELECT COUNT(*),并且引擎将无需引用表数据就能从索引单独回答查询。这应该可以加快速度,取决于MySQL如何存储和检索基数统计数据,可以使查询瞬间完成。

+0

id是AUTO_INCREMENT列,但似乎并没有加快速度......我仍然获得相同的速度 – fxuser 2012-04-17 17:45:28

+0

您需要一个大型数据集才能查看查询时间如何变化总数。尝试创建500万行并进行测试。 – 2012-04-17 17:47:28

+0

在1.2米行上需要0.2秒,所以我想在5米它将需要约1-1.5秒...不能这样缩小到像0.002或类似的东西?其他网站如何从db获得这样的数字如此之快?他们是否将它们存储在某个地方,并且在创建/删除新记录时增加/减少它们的数量? – fxuser 2012-04-19 12:56:30