• 记一条sql语句优化


     傻瓜级的。此sql语句存在于分销王系统中。

    查阅slow log ,时间设置1s

    发现很多

    SELECT r.*, goods_id, bn, name FROM sdb_goods_rate r, sdb_goods
    WHERE ((goods_2 = goods_id AND goods_1=4799) OR (goods_1 = goods_id AND goods_2 = 4799 AND manual='both')) AND rate > 99;

    主要是2个表的联立,相当于inner join吧。 条件是 goods_2= xx and goods_1=zz

    mysql> show create table sdb_goods_rate;
    -------------------------------------------------------------------------------------+
    | sdb_goods_rate | CREATE TABLE `sdb_goods_rate` (
    `goods_1` mediumint(8) unsigned NOT NULL,
    `goods_2` mediumint(8) unsigned NOT NULL,
    `manual` enum('left','both') DEFAULT NULL,
    `rate` mediumint(8) unsigned NOT NULL DEFAULT '1',
    PRIMARY KEY (`goods_1`,`goods_2`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 |

    可以看到goods_rate 的primary key 是 goods_1 ,goods_2 而我们用到的查询是 goods_2 ,goods_1 ,用不上我们的pk 索引。

    这点可以从explain里面来观察。

    mysql> explain SELECT r.*, goods_id, bn, name FROM sdb_goods_rate r, sdb_goods
    -> WHERE ((goods_2 = goods_id AND goods_1=2708) OR (goods_1 = goods_id AND goods_2 = 2708 AND manual='both')) AND rate > 99;
    +----+-------------+-----------+------+---------------+------+---------+------+-------+--------------------------------+
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
    +----+-------------+-----------+------+---------------+------+---------+------+-------+--------------------------------+
    | 1 | SIMPLE | sdb_goods | ALL | PRIMARY | NULL | NULL | NULL | 3024 | |
    | 1 | SIMPLE | r | ALL | PRIMARY | NULL | NULL | NULL | 23109 | Using where; Using join buffer |
    +----+-------------+-----------+------+---------------+------+---------+------+-------+--------------------------------+

    扫描都是all 全表扫描,产生了笛卡尔积,大概是 3000*23000 约等于69000000,非常大的一个数据量。

    我们这里创建索引

    create index idx_goods12 on sdb_goods_rate(goods_2,goods_1);

    然后再看执行计划,

    +----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+
    | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
    +----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+
    | 1 | SIMPLE | r | index_merge | PRIMARY,idx_goods12 | PRIMARY,idx_goods12 | 3,3 | NULL | 38 | Using sort_union(PRIMARY,idx_goods12); Using where |
    | 1 | SIMPLE | sdb_goods | ALL | PRIMARY | NULL | NULL | NULL | 3024 | Range checked for each record (index map: 0x1) |
    +----+-------------+-----------+-------------+---------------------+---------------------+---------+------+------+----------------------------------------------------+

    数据量大大减少,为38*3024=120000,数据量规模大概小了575倍,基本上0.1秒都不用,结果就出来了。

  • 相关阅读:
    PHP基础函数、自定义函数以及数组
    php 中 isset 和empty 的区别
    mysql中索引的使用
    mysql 中的增改查删(CRUD)
    mysql语句应该注意的问题
    《zw版·Halcon-delphi系列原创教程》 水果自动分类脚本(机器学习、人工智能)
    《zw版·Halcon-delphi系列原创教程》 2d照片-3d逆向建模脚本
    《zw版·Halcon-delphi系列原创教程》简单的令人发指,只有10行代码的车牌识别脚本
    《zw版·Halcon-delphi系列原创教程》航母舰载机·视觉定位标志的识别代码
    zw版_zw中文增强版Halcon官方Delphi例程
  • 原文地址:https://www.cnblogs.com/gqdw/p/3163510.html
Copyright © 2020-2023  润新知