当(内部)加入这个表时,是什么导致了内存泄漏?

umuewwlo  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(422)

我脑子里有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脚本在尝试执行查询时内存不足。
以下是我的表格结构:
表1

+----------+---------+------+-----+---------+-------+
| Field    | Type    | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| epid     | int(11) | YES  |     | NULL    |       |
| model_id | int(11) | YES  |     | NULL    |       |
+----------+---------+------+-----+---------+-------+

表2

+----------------+--------------+------+-----+---------+-------+
| 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    |       |
+----------------+--------------+------+-----+---------+-------+

表3

+-----------------+-------------+------+-----+---------+----------------+
| 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中)。取消限制后,仍在运行的建议。。。所以不太清楚。安东关于使用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,我可以像那样分解查询并构建数组,所以我想这可能解决了这个问题——我想我还能做些什么来减少执行时间吗?

clj7thdc

clj7thdc1#

基于每个人的评论等,我设法执行了一些事情,使我的查询运行得更快,并没有崩溃我的脚本地狱。
1) 索引
我在我的网站上创建了一个索引 table_three 为了这个领域 fit_model_id :

CREATE INDEX fit_model ON `table_three` (`fit_model_id`);

这使得我的limit1查询的执行时间从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 在这些table上:
表1
表3
这使得我的脚本和我的查询一如既往地快速。然而,我遇到的问题是一个大数据集,所以我让查询在mysql cli中运行,同时将每个脚本的运行时间限制增加1000,以帮助索引过程,在它开始崩溃之前,一直运行到30k行。
cli用了31分8秒完成。所以我做了这个:
31 x 60=1860年
1860 + 8 = 1868
1868 / 448476 = 0.0042
所以每行花了0.0042秒来完成-在我眼里这已经足够快了。
感谢大家的评论和帮助我调试和修复问题:)

fcg9iug3

fcg9iug32#

根据评论,正确答案如下:
如果长时间执行select语句,请在select之前添加explain语句
检查是否 possible_keys 在特定表的子查询中为空。
为步骤2中找到的表添加外键。如果是大表,建议调整max\u execution\u time变量(可以针对单个查询执行)
在大量插入/更新/删除操作的情况下,优化表还可以调整性能。

相关问题