我在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)
答案 0 :(得分:3)
以下是一些潜在的改进:
答案 1 :(得分:1)
提高绩效的一些想法
而不是在SQL(100/18)中进行计算,而不是像这样替换它
HAVING(COUNT(table2.ID)*(5.5555))> = 50
(因为table2.ID现在是一个bigint,数学比较必须稍快一些)
正如我所看到的,like子句在这个查询中至关重要,即使它很昂贵,如果你索引table1.attribute1也会更好。
希望这会有所帮助