zoukankan      html  css  js  c++  java
  • 记一条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秒都不用,结果就出来了。

  • 相关阅读:
    【六校联合训练 省选 #20】快递
    IOError: cannot open resource
    [已解决]运行gunicorn失败:[ERROR] Connection in use 127.0.0.1 8080
    windows下通过navicat for mysql连接centos6.3-64bit下的MySQL数据库
    在centos7中使用yum安装mysql数据库并使用navicat连接
    centos出现“FirewallD is not running”怎么办
    [linux]centos7下解决yum install mysql-server没有可用包
    CentOS 7安装Python3
    flask——CSRFToken保护
    python 获取当前文件夹下所有文件名
  • 原文地址:https://www.cnblogs.com/gqdw/p/3163510.html
Copyright © 2011-2022 走看看