MySQL查询速度极慢

时间:2012-04-21 23:05:06

标签: php mysql performance optimization

我在MySQL中有两个表,table1有1,013,347个实体和38个属性,table2有7,343,905个实体和10个属性。在以下查询中(应该获取分页的行数),table1.ID是PK,table2.ID是它的FK(两者都被索引),如果HAVING子句超过一定百分比,则获取值,在这种情况下50%

SELECT SQL_CALC_FOUND_ROWS * 
FROM table1 INNER JOIN table2 ON table1.ID = table2.ID 
WHERE table1.attribute1 LIKE 'D%' 
GROUP BY table2.ID 
HAVING (COUNT(table2.ID) * (100/18)) >= '50'

即使在我发布的简化状态下,此查询也需要不少于5分钟的时间通过命令行运行。我知道我必须对查询进行更改,PHP代码(值'50'和'D'通过PHP变量分配)和/或我的MySQL配置以加快速度(我正在使用最新的XAMPP,默认配置)。任何帮助将不胜感激。

EDIT1:除了VARCHAR(9)的ID属性外,所有属性都是TINYTEXT。

EDIT2:EXPLAIN SELECT ...返回:

+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+
| id | select_type | table  | type | possible_keys | key         | key_len | ref  | rows    | Extra                           |
+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+
|  1 | SIMPLE      | table2 | ALL  | NULL          | NULL        | NULL    | NULL | 7343905 | Using temporary; Using filesort |
|  1 | SIMPLE      | table1 | ref  | ID            | ID          | 29      | func |       1 | Using where                     |
+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+
2 rows in set (0.00 sec)

2 个答案:

答案 0 :(得分:3)

以下是一些潜在的改进:

  • 您正在使用类型为VARCHAR(9)的ID,并且您正在使用这些字段进行连接。引入整数代理键而不是varchars来加速连接可能是个好主意。见this discussion
  • LIKE运营商通常很贵。考虑你的用法;像Marc建议的那样,你应该索引table1.attribute1。
  • 也许您可以通过省略LIKE来加快查询速度:例如,您可以使用RIGHT()而不是使用“D%”,但我不确定它是否会更快。如果表中的数据不经常更改,则可以创建一个新的索引列,其中预先切割table1.attribute1值;但它取决于php脚本在LIKE之后插入的值。

答案 1 :(得分:1)

提高绩效的一些想法

  1. index table2.ID(必须)和table1.ID也是
  2. 如果可能,使id列bigint和table1.attribute1成为varchar。请注意根据列的假定数据长度
  3. 为varchar列定义合适的大小
  4. 而不是在SQL(100/18)中进行计算,而不是像这样替换它

    HAVING(COUNT(table2.ID)*(5.5555))> = 50

  5. (因为table2.ID现在是一个bigint,数学比较必须稍快一些)

    正如我所看到的,like子句在这个查询中至关重要,即使它很昂贵,如果你索引table1.attribute1也会更好。

    希望这会有所帮助