临时表或视图的替代方法,用于优化小表上的重复查询

时间:2014-04-19 03:10:38

标签: mysql sql query-optimization

我有一张约有40,000行的表格。每个都有一个以空格分隔的数字列表,范围从1到100.示例行在列中有唯一的标识名称,后跟另一列中的“4 8 18 32”。

我希望将名称的自由文本搜索与包含特定数字的行数的计数结合起来。因此,例如,给我计算与%word%匹配的行数以及每个数字1到100的数量。这是一百个查询。如果上面的“4 8 18 32”是表中的唯一匹配,那么计数将是1:0,2:0,3:0,4:1,... 8:1,...... 32: 1。

目前,我正在尝试使用最小令牌长度为1的InnoDB FULLTEXT索引来执行此操作,然后以二进制模式进行搜索。我的查询看起来像这样:

(SELECT COUNT(*) FROM `table` WHERE MATCH (`numbers`) AGAINST ('+34' IN BOOLEAN MODE) AND `name` LIKE '%word%') as `34`,
(SELECT COUNT(*) FROM `table` WHERE MATCH (`numbers`) AGAINST ('+35' IN BOOLEAN MODE) AND `name` LIKE '%word%') as `35`,

并加入一个结果。这需要大约两到三秒,这是一段很长的时间。

我尝试使用临时表进行LIKE匹配,然后只做布尔模式搜索数字,但我不能在查询中多次重用临时表引用,并且在这里重复使用了一百次。我也试过创建一个LIKE部分的视图,但没有看到太多的加速。告诉视图使用algorithm = temptable是不可能的,因为全文索引不能转移。

我是否以一种根本不正确的方式使用数据库?是否有一种策略可以显着提高速度?

1 个答案:

答案 0 :(得分:1)

而不是100个单独的查询,我只会针对该表尝试一个查询:

SELECT 
       -- using CASE expression --
       SUM( case when `numbers` like '%+34%' and `name` LIKE '%word%'
                 then 1 else 0 end ) As `34`,
       -- or using IF ---
       SUM( IF( `numbers` like '%+35%' and `name` LIKE '%word%', 1, 0 )) As `35`
       .......
FROM table;

此查询对表执行全表扫描,但仅扫描一次,而不是一系列100次扫描。
可能会更快 - 尝试一下。
全表扫描不是邪恶的,索引并不总是好的。