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秒都不用,结果就出来了。

  • 相关阅读:
    MySQL语法
    Linux常用命令大全
    触发器使用UTL_SMTP包发送邮件
    MySQL——触发器的创建和使用总结
    MySQL数据库备份
    Nginx配置文件(nginx.conf)配置详解
    JS弹出框,打开文件,保存文件,另存为。。。。
    java excel两种操作方式
    Zookeeper的优缺点
    activemq linux安装
  • 原文地址:https://www.cnblogs.com/gqdw/p/3163510.html
Copyright © 2011-2022 走看看