如何更快地进行GROUP BY SUBSTRING查询?

时间:2009-10-20 21:11:34

标签: mysql sql group-by substring

我有一个具有以下结构的表:

id bigNumber           text
1  1200321030011010233 "an item with some text"
2  1200321030011014563 "another item with some more text"
3  3120323434432211133 "more...."
.
.
.

该表包含大约50,000条记录。我想做以下查询,但速度很慢:

  SELECT COUNT(*), 
         bigNumber 
    FROM items 
GROUP BY substr(bigNumber, 1, X)

其中X从2到19变化。

是否可以更快地创建19列,每列中包含部分数字以便能够使用索引?

3 个答案:

答案 0 :(得分:2)

我建议不要使用19个单独的列,可能只有3个或4个,如下所示:

alter table items
add column bignumber_l1 char(1)
, add column bignumber_l3 varchar(3)
, add column bignumber_l6 varchar(6);

update items
set bignumber_l1 = left(bignumber, 1)
 , bignumber_l3 = left(bignumber, 3)
 , bignumber_l6 = left(bignumber, 6);

alter table items
add index bignumber_l1
, add index bignumber_l3
, add index bignumber_l6;

然后当你查询x长度的字符串时,用最长的匹配写下查询而不用更长时间:

  SELECT COUNT(*), 
         bigNumber 
    FROM items 
GROUP BY bignumber_l3, substr(bigNumber, 1, 4)

此查询可以使用索引,并可能显着提高您的性能。请注意,由于您要求整个表,因此即使使用上面的索引,mysql也可能决定您需要进行表扫描,因此您可能需要使用FORCE INDEX

答案 1 :(得分:0)

您可以在不添加任何列的情况下使用索引,只需在bigNumber列上创建索引:

create index bignum_index on items (bigNumber);

varchar上的索引(bigNumber是varchar,对吧?)可以用来查找任何字符串前缀。

那就是说,你需要做一个全表扫描来回答你的查询,所以一个索引对你没那么大帮助。

答案 2 :(得分:-1)

我认为你要找的结果是LIKE _X%。这不会使用索引。

SELECT count(*) FROM items WHERE bignumber LIKE "_2%"
SELECT count(*) FROM items WHERE bignumber LIKE "_19%"

_表示一个字符

%表示任意数量的字符

有关详细信息,请参阅MySQL docs