我在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代码(通过PHP变量分配值“ 50”和“ D”)和/或对我的MySQL配置进行更改以加快处理速度(我正在使用具有默认配置的最新XAMPP).任何帮助将不胜感激.
EDIT1:除ID属性为VARCHAR(9)外,所有属性均为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)
解决方法:
以下是一些潜在的改进:
>您正在使用类型为VARCHAR(9)的ID,并且正在使用这些字段进行联接.引入整数代理键而不是varchars可能是一个好主意,以加快连接速度.参见this discussion.
> LIKE运算符通常很昂贵.考虑您的用法;如Marc建议的那样,您应该索引table1.attribute1.
>也许可以通过完全省略LIKE来加快查询速度:例如,可以使用RIGHT()代替使用’D%’,尽管我不确定它是否会更快.如果表中的数据很少更改,则可以使用table1.attribute1值开始时切入的值创建一个新的索引列.但是,它取决于php脚本在LIKE之后插入了哪些值.