代码之家  ›  专栏  ›  技术社区  ›  treyBake user1850175

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

  •  5
  • treyBake user1850175  · 技术社区  · 7 年前

    我脑子里有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;
    

    INNER JOIN `table_three` f ON `mem`.`model_id` = f.`fit_model_id`
    

    以下是我的表格结构:

    表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,我可以像那样分解查询并构建数组,所以我想这可能解决了这个问题——我想我还能做些什么来减少执行时间吗?

    2 回复  |  直到 7 年前
        1
  •  3
  •   treyBake user1850175    7 年前

    基于每个人的评论等,我设法执行了一些事情,使我的查询运行得更快,并没有崩溃我的脚本地狱。

    1) 索引

    table_three 为了这个领域 fit_model_id

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

    这使得我的limit1查询的执行时间从16秒变为0.03秒(在MYSQL CLI中)。

    不过,100行左右的时间还是比我想象的要长得多。

    我创建了一个外键 table_one . model_id = . 安装\型号\ 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 在这些桌子上:

    • 表1
    • 表3

    CLI用了31分8秒完成。所以我做了这个:

    31 x 60=1860年

    1868 / 448476 = 0.0042

    所以每行花了0.0042秒来完成-在我眼里这已经足够快了。

    感谢大家的评论和帮助我调试和修复问题:)

        2
  •  2
  •   Anton    7 年前

    根据评论,正确答案如下:

    1. 如果长时间执行select语句,请在select之前添加EXPLAIN语句
    2. 检查是否 possible_keys
    3. 添加 FOREIGN KEY
    4. 在大量插入/更新/删除操作的情况下,优化表还可以调整性能。
    推荐文章