• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > MySQL优化

MySQL优化

作者:Nick_666的博客 字体:[增加 减小] 来源:互联网 时间:2017-09-02

Nick_666的博客通过本文主要向大家介绍了mysql等相关知识,希望本文的分享对您有所帮助

 

1、SQL索引优化

使用explain查询SQL的执行计划

explain返回各列的含义

  • table:显示这一行的数据是关于哪张表的
  • type:这是重要的列,显示连接使用了何种类型。从最好到最差的连续类型为const,eq_reg,ref,range,index和ALL(没有where从句,表扫描)。
  • possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引
  • key:实际使用的索引。如果为NULL,则没有使用索引
  • key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好
  • ref:显示索引的哪一列被使用了,如果可能的话,是一个常数
  • rows:mysql认为必须检查的用来返回请求数据的行数
  • extra列需要注意的返回值
  • Using filesort:看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序,根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行
  • Using temporary 看到这个的时候,也需要优化,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上。

查询最后支付时间----优化MAX()函数

 

mysql> explain select max(payment_date) from payment \G;

 

*************************** 1. row ***************************

           id: 1

  select_type: SIMPLE

        table: payment

   partitions: NULL

         type: ALL

possible_keys: NULL

          key: NULL

      key_len: NULL

          ref: NULL

         rows: 16086

     filtered: 100.00

        Extra: NULL

1 row in set, 1 warning (0.00 sec)

 

ERROR: 

No query specified

可以查看到:type:ALL是表扫描操作;没有任何索引,rows非常大,IO效率非常低。
如何优化这个SQL:通常情况下建立索引:
create index idx_paydate on payment(payment_date);
这样在次执行
explain select max(payment_date) from payment;
可以看到Extra:select tables optimized away;可以通过索引进行操作,大大减少了IO操作

mysql> create index idx_paydata on payment(payment_date);

Query OK, 0 rows affected (0.05 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> explain select max(payment_date) from payment \G;

*************************** 1. row ***************************

           id: 1

  select_type: SIMPLE

        table: NULL

   partitions: NULL

         type: NULL

possible_keys: NULL

          key: NULL

      key_len: NULL

          ref: NULL

         rows: NULL

     filtered: NULL

        Extra: Select tables optimized away

1 row in set, 1 warning (0.00 sec)

 

ERROR: 

No query specified

 

mysql> DROP INDEX idx_paydata on payment;

Query OK, 0 rows affected (0.01 sec)

Records: 0  Duplicates: 0  Warnings: 0

 

mysql> explain select max(payment_date) from payment \G;

*************************** 1. row ***************************

           id: 1

  select_type: SIMPLE

        table: payment

   partitions: NULL

         type: ALL

possible_keys: NULL

          key: NULL

      key_len: NULL

          ref: NULL

         rows: 16086

     filtered: 100.00

        Extra: NULL

1 row in set, 1 warning (0.00 sec)

 

ERROR: 

No query specified

 

mysql> 


在一条SQL中同时查出2006年和2008年电影的数量----优化count()函数
错误方式:
SELECT COUNT(release_year='2006' OR release_year='2008') FROM film;
无法分开计算2006和2008年的电影数量,结果是之和。
select count(*) FROM film WHERE release_year='2006' AND release_year='2007';
release_year不可能同时为2006和2007,因此有逻辑错误
正确的方式:

 

mysql> select count(release_year='2006' or null) as '2006film', count(release_year='2008' or null) as '2008film' from film;

 

 

+----------+----------+

| 2006film | 2008film |

+----------+----------+

|      999 |        1 |

+----------+----------+

1 row in set (0.00 sec)

 

mysql> 

 

count中‘or null’的作用是:当年份不是2006/2008时返回null,而null在count(id)中时不会计数的,count(*)会将null计算进去。

 

mysql> SELECT COUNT(release_year='2007') FROM film;          

+----------------------------+

| COUNT(release_year='2007') |

+----------------------------+

|                       1000 |

+----------------------------+

1 row in set (0.00 sec)

 

mysql> SELECT COUNT(release_year='2007' or null) FROM film;

+------------------------------------+

| COUNT(release_year='2007' or null) |

+------------------------------------+

|                                  0 |

+------------------------------------+

1 row in set (0.00 sec)

 

mysql> 

 


4.子查询的优化
通常情况下,需要把子查询优化为join查询,但在优化时要注意关联键是否有一对多的关系,要注意重复数据。
我们新建一张表t1
create table t1(tid int);
插入一条数据insert into t1 values(1);
进行子查询:select * from t where t.id in (select * from t1.tid from t1);
返回t表id在t1表中的数据
优化成join的形式:
select t.id from t join t1 on t.id=t1.tid;
这两种形式返回的结果是一样的

需要注意的是:
如果在t1表中,添加一条数据:insert into t1 values(1);
然后在分别执行这两种形式的查询:
发现使用select * from t where t.id in (select * from t1.tid from t1);查询出来的结果是一条数据。而select t.id from t join t1 on t.id=t1.tid;是两条数据,说明有重复数据,我们可以使用distinct去重。 JOIN: 如果表中有至少一个匹配,则返回行
LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
FULL JOIN:

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2018-12-05mysql查询扩展技术教程
  • 2018-12-05mysql日期和时间类型
  • 2018-12-05mysql 查看版本的方法图文演示
  • 2018-12-05MySQL5.6基本配置详解
  • 2018-12-05MySQL_实现组内排序-Oracle中的rank()函数的功能
  • 2018-12-05EXP-00056: ORACLE error 29275 encountered
  • 2018-12-05如何解决MySQL 5.0.16中的乱码问题
  • 2018-12-05浅谈MySQL漂流记(二)
  • 2018-12-05SQL Server中的执行引擎入门 图解
  • 2018-12-05分页存储过程(用存储过程实现数据库的分页代码)

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • mysql-springjdbc 连接数据库,超过8小时没有连接,断开了与数据库的连接怎么办
    • 分页存储过程(二)在sqlserver中返回更加准确的分页结果
    • mysqli多查询特性 实现多条sql语句查询
    • 详解mysql建立索引的使用办法及优缺点分析_MySQL
    • MySQL使用innobackupex备份连接服务器失败的代码案例
    • mysql命令行还原phpMyAdmin导出的含有中文的SQL文件
    • 让sql2005运行在独立用户下出现 WMI 提供程序错误的解决方式
    • MySQL安装详解图文版(V5.5 For Windows)
    • mysql嵌套查询和联表查询优化方法
    • 分享csv导入数据到mysql实例

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有