设为首页 收藏本站
查看: 1282|回复: 6

[经验分享] MySQL索引与查询优化

[复制链接]

尚未签到

发表于 2013-3-17 17:02:17 | 显示全部楼层 |阅读模式

概述


           企业应用软件中,在数据存储方面选择为DBMS(数据库管理系统)。当数据量增多后,对数据的查询和分析在速度上会有很大的影响。原因如下:
        1、数据文件存储在磁盘上,每次读取会有I/O消耗。
        2、I/O性能始终是数据读取的瓶颈。数据随机存放,每一次的I/O操作消耗大量的CPU时间。为了降低I/O操作对DBMS查询速度的限制,DBMS引入了索引的概念。

       下面会以MySQL为例来说明,例子如下:
       假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录。如果没有索引,查询将对整个表进行扫描,最坏的情况下,如果所有数据页都不在内存,需要读取10^4个页面,如果这10^4个页面在磁盘上随机分布,需要进行10^4次I/O,假设磁盘每次I/O时间为10ms(忽略数据传输时间),则总共需要100s(但实际上要好很多很多)。如果对之建立B-Tree索引,则只需要进行log100(10^6)=3次页面读取,最坏情况下耗时30ms。这就是索引带来的效果,很多时候,当你的应用程序进行SQL查询速度很慢时,应该想想是否可以建索引。

索引

        索引类型


        MySQL的数据库引擎有两种,一是MyISAM另一种是INNODB。对于这两种的区别可以参看以下内容:
http://www.iyunv.com/villion/archive/2009/07/09/1893762.html

        BTree是INNODB的索引算法,m阶的BTree树,满足如下内容
        1、所有节点最多有m个子节点
        2、根节点至少有两个子节点
        3、除根节点和叶子节点外,其它节点至少有m/2取上整个节点
        4、所有叶子节点在同一层
        5、有k个节点的非叶子节点恰好有k-1个关键字。
       其结构如下:


1363425549_1080.jpg


MySql执行计划


       使用explain关键字,通过该关键字可以查看mysql的执行计划。执行计划的参数如下:
1363425772_4264.jpg

查询优化经验


               (1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。


               (2)简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。


               (3)尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。这个在实际开发中应该要注意到,避免出现空值。


               (4)如果对多列进行索引(组合索引),列的顺序非常重要,MySQL仅能对索引最左边的前缀进行有效的查找。

            例如:存在组合索引index_name(name,pwd)。

查询语句select * from t5 where name='1' and pwd='2'能够使用该索引。
查询语句select * from t5 where name='1' 也能够使用该索引。
查询语句select * from t1 where pwd='2'不能够使用该索引,因为没有组合索引的引导列,即,要想使用pwd列进行查找,必需出现name等于某值。
例子如下:

mysql> desc t5;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| name    | varchar(20) | NO   | MUL | NULL    |                |
| pwd     | varchar(20) | NO   |     | NULL    |                |
| sex     | int(11)     | YES  |     | 0       |                |
| age     | int(11)     | YES  | MUL | 0       |                |
| address | varchar(30) | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
mysql> explain select * from t5 where name='n1'\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: t5
    type: ref
possible_keys: index_name
     key: index_name
    key_len: 62
     ref: const
    rows: 1
   Extra: Using where; Using index
1 row in set (0.00 sec)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
mysql> explain select * from t5 where pwd='n1'\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: t5
    type: index
possible_keys: NULL
     key: index_name
    key_len: 124
     ref: NULL
    rows: 5
   Extra: Using where; Using index
1 row in set (0.00 sec)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

mysql> explain select * from t5 where name='n1' and pwd='n1'\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: t5
    type: ref
possible_keys: index_name
     key: index_name
    key_len: 124
     ref: const,const
    rows: 1
   Extra: Using where; Using index
1 row in set (0.00 sec)

=================================================================================================================================== (5)like查询

mysql> explain select * from t5 where name like '%p1'\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: t5
    type: ALL
possible_keys: NULL
     key: NULL
    key_len: NULL
     ref: NULL
    rows: 5
   Extra: Using where
1 row in set (0.00 sec)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

mysql> explain select * from t5 where name like 'p1%'\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: t5
    type: range
possible_keys: index_name
     key: index_name
    key_len: 62
     ref: NULL
    rows: 1
   Extra: Using where
1 row in set (0.00 sec)

===================================================================================================================================(6)null或者not null查询

mysql> explain select * from t5 where address is null\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: t5
    type: ALL
possible_keys: NULL
     key: NULL
    key_len: NULL
     ref: NULL
    rows: 45
   Extra: Using where
1 row in set (0.00 sec)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

mysql> explain select * from t5 where name is not null\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: t5
    type: ALL
possible_keys: index_name
     key: NULL
    key_len: NULL
     ref: NULL
    rows: 45
   Extra: Using where
1 row in set (0.00 sec)

=================================================================================================================================== (7) or查询,同时有索引,否则失效

mysql> explain select * from t5 where age=0 or address='1'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t5
         type: ALL
possible_keys: index_age
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 45
        Extra: Using where
1 row in set (0.00 sec)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

mysql> explain select * from t5 where age=0 or id=1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t5
         type: index_merge
possible_keys: PRIMARY,index_age
          key: index_age,PRIMARY
      key_len: 5,4
          ref: NULL
         rows: 6
        Extra: Using union(index_age,PRIMARY); Using where
1 row in set (0.00 sec)

==================================================================================================================================(8)and查询,同时有索引,否则失效

mysql> explain select * from t5 where id=1 and address='11'\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: NULL
    type: NULL
possible_keys: NULL
     key: NULL
    key_len: NULL
     ref: NULL
    rows: NULL
   Extra: Impossible WHERE noticed after reading const tables
1 row in set (0.00 sec)

=================================================================================================================================== (9)如果列是int类型,但是给的是string类型那么mysql会放弃使用索引
mysql> explain select * from t5 where pwd=1\G
*************************** 1. row ***************************
      id: 1
   select_type: SIMPLE
   table: t5
    type: ALL
possible_keys: NULL
     key: NULL
    key_len: NULL
     ref: NULL
    rows: 45
   Extra: Using where
1 row in set (0.00 sec)

优化一般步骤


(1)定期优化表和检测表


check table tabelname检测表是否错误
optimize table sales;

(2)慢查询日志


开启,找到查询慢的语句
show status like "slow_queries";
      slow_launch_time
      slow_query_log
      query_log_file
show variables like "%slow%";


mysql> show variables like "%slow%";
+---------------------+---------------------------------------------------------
-----+
| Variable_name       | Value
   |
+---------------------+---------------------------------------------------------
-----+
| log_slow_queries    | OFF
   |
| slow_launch_time    | 2
   |
| slow_query_log      | OFF
   |
| slow_query_log_file | C:\ProgramData\MySQL\MySQL Server 5.1\Data\Belen-PC-slow
.log |
+---------------------+---------------------------------------------------------
-----+


show variables like "%long%";慢查询时间
show status like 'Handler_read%';该值越高说明有好多表需要索引。


(3)定位执行效率较低的SQL语句



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-4018-1-1.html 上篇帖子: MySQL5.6 GTID模式,同步复制报错不能跳过解决方法 下篇帖子: phpMyAdmin"请检查 PHP 或网站服务器日志,并正确配置 PHP 安装" 解决方法 查询 优化

尚未签到

发表于 2013-3-19 21:17:57 | 显示全部楼层
锻炼肌肉,防止挨揍!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-5-18 04:58:05 | 显示全部楼层
生我之前谁是我,生我之后我是谁?

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-5-22 14:44:55 | 显示全部楼层
美女未抱身先走,常使色狼泪满襟。。。。。。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-5-29 15:00:32 | 显示全部楼层
修养的艺术,其实就是说谎的艺术。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-6-5 14:36:08 | 显示全部楼层
所有刻骨铭心的爱都灵魂游离于床上的瞬间!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-6-14 07:49:44 | 显示全部楼层
一时的冲动,子孙的危机!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表