我脑中有一条SQL,它将并且应该在1秒内运行:
SELECT mem.`epid`,
mem.`model_id`,
em.`UKM_Make`,
em.`UKM_Model`,
em.`UKM_CCM`,
em.`UKM_Submodel`,
em.`Year`,
em.`UKM_StreetName`,
f.`fit_part_number`
FROM `table_one` AS mem
INNER JOIN `table_two` em ON mem.`epid` = em.`ePID`
INNER JOIN `table_three` f ON `mem`.`model_id` = f.`fit_model_id`
LIMIT 1;
当我在终端中运行时,此SQL将在16秒内执行。但是,如果我删除该行:
INNER JOIN `table_three` f ON `mem`.`model_id` = f.`fit_model_id`
然后它会在0.03秒内执行。不幸的是,我不确定如何调试MYSQL性能问题。这导致我的PHP脚本用尽了内存,无法执行查询。
这是我的表结构:
table_one
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| epid | int(11) | YES | | NULL | |
| model_id | int(11) | YES | | NULL | |
+----------+---------+------+-----+---------+-------+
table_two
+----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| ePID | int(11) | NO | | NULL | |
| UKM_Make | varchar(100) | NO | | NULL | |
| UKM_Model | varchar(100) | NO | | NULL | |
| UKM_CCM | int(11) | NO | | NULL | |
| UKM_Submodel | varchar(100) | NO | | NULL | |
| Year | int(11) | NO | | NULL | |
| UKM_StreetName | varchar(100) | NO | | NULL | |
| Vehicle Type | varchar(100) | NO | | NULL | |
+----------------+--------------+------+-----+---------+-------+
table_three
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| fit_fitment_id | int(11) | NO | PRI | NULL | auto_increment |
| fit_part_number | varchar(50) | NO | | NULL | |
| fit_model_id | int(11) | YES | | NULL | |
| fit_year_start | varchar(4) | YES | | NULL | |
| fit_year_end | varchar(4) | YES | | NULL | |
+-----------------+-------------+------+-----+---------+----------------+
以上内容是从describe $table_name
我明显缺少什么吗?如果没有,我该如何找出包含table_three
的原因导致如此缓慢的响应时间?
编辑一个:
建立索引建议(使用CREATE INDEX fit_model ON table_three (fit_model_id)
后,它将在0.00秒内执行查询(在MYSQL中)。删除限制后,仍在执行建议后仍在运行...所以还不够。Anton关于使用EXPLAIN我用它并得到以下输出:
+------+-------------+-------+------+---------------+-----------+---------+----------------------+-------+-------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+-----------+---------+----------------------+-------+-------------------------------------------------+
| 1 | SIMPLE | mem | ALL | NULL | NULL | NULL | NULL | 5587 | Using where |
| 1 | SIMPLE | f | ref | fit_model | fit_model | 5 | mastern.mem.model_id | 14 | |
| 1 | SIMPLE | em | ALL | NULL | NULL | NULL | NULL | 36773 | Using where; Using join buffer (flat, BNL join) |
+------+-------------+-------+------+---------------+-----------+---------+----------------------+-------+-------------------------------------------------+
编辑两次
我使用以下查询根据建议添加了外键:
ALTER TABLE `table_one`
ADD CONSTRAINT `model_id_fk_tbl_three`
FOREIGN KEY (`model_id`)
REFERENCES `table_three` (`fit_model_id`)
MYSQL仍在执行命令-行很多,因此请半途而废。借助PHP,我可以像这样分解查询并构建数组,因此我想这可能解决了这个问题-想做更多的事情来尝试减少执行时间吗?
答案 0 :(得分:3)
基于每个人的评论等。我设法执行了一些操作,这些操作使我的查询运行得更快,并且不会崩溃我的脚本。
1)索引
我在table_three
上为字段fit_model_id
创建了一个索引:
CREATE INDEX fit_model ON `table_three` (`fit_model_id`);
这使我的LIMIT 1查询的执行时间从16秒变为0.03秒(在MYSQL CLI中)。
但是,大约100行仍然比我想象的要花费更长的时间。
2)外键
我创建了一个使用以下查询链接table_one
。model_id
= table_three
。fit_model_id
的外键:
ALTER TABLE `table_one`
ADD CONSTRAINT `model_id_fk_tbl_three`
FOREIGN KEY (`model_id`)
REFERENCES `table_three` (`fit_model_id`)
这肯定有帮助,但仍然觉得可以做更多的事情。
3)优化表
然后我在这些表上使用了OPTIMIZE TABLE
:
然后,这使我的脚本可以正常工作,并且查询比以往任何时候都快。但是,我遇到的问题是一个大数据集,所以我让查询在MYSQL CLI中运行,同时将每个脚本运行时间的LIMIT增加1000,以帮助索引过程,直到开始崩溃前一直达到3万行。
CLI完成了31分8秒。所以我这样做了:
31 x 60 = 1860
1860 + 8 = 1868
1868/448476 = 0.0042
因此每一行需要0.0042秒才能完成-在我眼中这足够快。
感谢大家发表评论并帮助我调试和解决问题:)
答案 1 :(得分:2)
基于评论的正确答案如下:
possible_keys
是否为空。