mysql-优化一

建立索引

建立索引是优化查询的一种方式,我们通常会对where列上建立相关索引,可以是单列的索引,也可以是复合索引。

加索引要注意

在where、order by的相关列上可以考虑添加索引;

如果where列中已经存在索引,order by列的索引(假设存在)不会被利用(explain显示using filesort就表示order by没有用到索引,where列与order by列建立复合索引,就可以了,也可以在业务层进行排序);

where列中多个“且”条件列都添加了索引,mysql只会利用“价值最大”的一列(这种情况可以考虑复合索引);

复合索引的最前匹配原则;

字符串列的索引,“abc%”会走索引,“%abc”不会走索引;

为字符串建立索引,最好遵循短索引,比如一个CHAR(255)的列,如果该列值的前10位就可保证唯一(或者区分度很高,近似唯一),就可以以前10为建立索引;

尽量避免使用否定条件,如NOT IN、IS NOT、NOT LIKE、!=、<>等(否定句不走索引);

理解以上一系列的规则并不困难,比如说多个“且”条件只会利用一个索引,而多个“或”条件则可能会利用多个索引。因为对于“且”条件,使用一个索引找到相关数据项后只需要在这些数据项中进一步条件过滤就可以了,没有必要再次通过索引做任何事,而对于“或”条件,一个索引找到的条目可能并不满足其他条件,这就需要多次经过索引进行查找(当然也并非一定会经过索引查找,mysql会做出“明智”的决定)。

NULL值的索引

网上对where name is null这种查询走不走索引说法不一,有些观点说不走索引,推荐将列均设为NOT NULL,将null值替换为0、""等形式。但我从官方文档找到了相关说明,并且也做了相应测试,NULL列确实可以走索引。

MySQL can perform the same optimization on col_name IS NULL that it can use for col_name = constant_value.
For example, MySQL can use indexes and ranges to search for NULL with IS NULL.

Examples

1 SELECT * FROM tbl_name WHERE key_col IS NULL;
2
3 SELECT * FROM tbl_name WHERE key_col <=> NULL;
4
5 SELECT * FROM tbl_name
6   WHERE key_col=const1 OR key_col=const2 OR key_col IS NULL;

附:可以通过explain查看查询是否使用了索引;

  通过show profiles可以查看查询耗时,show profile for query n可以查询某条查询语句的详细执行情况。数据库默认是不开启profiling的,变量profiling是用户变量,每次都得通过set profiling=1;重新启用,可以通过set profiling=0关闭。

  

=、IS、LIKE

IS通常只用于NULL;=就是等值判断,注意,NULL与任何值都不相等,包括它自己;LIKE常用于字符串匹配,如“a_b%”,_代表任意一个字符,%代表任意个字符。

IN、JOIN和EXISTS

select * from t1 where exists (select null from t2 where t2.x=t1.x);的执行逻辑相当于

items = select * from t1
for x in items
   loop
      if ( exists ( select null from t2 where t2.x = x.x )
      then
         OUTPUT THE RECORD
      end if
end loop

select * from t1 where t1.x in (select distinct x from t2);的执行逻辑相当于

select *
  from t1, ( select distinct x from t2 ) t2
where t1.x = t2.x;

根据以上执行逻辑可以推断,外表为大表时适合使用in(因为mysql会建立一个内表查询结果的临时表,然后利用外表索引与临时表做联合,这种情况,临时表不宜过大,join和in类似,省去了临时表,性能比in要好一些),内表为大表时适合使用exists(因为查询会遍历外表项,外表越大遍历项就越多,而内表可以使用索引)

NOT EXISTS依旧会使用内表的索引,而NOT IN则不会再利用外表的索引,但依然会使用临时表,所以并不意味着NOT EXIST一定优于NOT IN,如果外表远远大于内表,NOT IN是有优势的,反之则应当选用NOT EXISTS

隐式转换

  • If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe <=> equality comparison operator. For NULL <=> NULL, the result is true. No conversion is needed.
  • If both arguments in a comparison operation are strings, they are compared as strings.
  • If both arguments are integers, they are compared as integers.
  • Hexadecimal values are treated as binary strings if not compared to a number.
  • If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to IN()! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.
  • A single-row subquery from a table or tables is not considered a constant. For example, if a subquery returns an integer to be compared to a DATETIME value, the comparison is done as two integers. The integer is not converted to a temporal value. To compare the operands as DATETIME values, use CAST() to explicitly convert the subquery value to DATETIME.
  • If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.
  • In all other cases, the arguments are compared as floating-point (real) numbers.

Examples

mysql> select 1+1;
+-----+
| 1+1 |
+-----+
|   2 |
+-----+

mysql> select ‘a‘ + ‘55‘;
+------------+
| ‘a‘ + ‘55‘ |
+------------+
|         55 |
+------------+

mysql> select 55 = 55;
+--------------+
| 55 = 55 |
+--------------+
|            1 |
+--------------+

mysql> select ‘55aaa‘ = 55;
+--------------+
| ‘55aaa‘ = 55 |
+--------------+
|            1 |
+--------------+

mysql> select ‘aaa55‘ = 55;
+--------------+
| ‘aaa55‘ = 55 |
+--------------+
|            0 |
+--------------+

隐式类型转换会引发安全和性能问题

安全问题在于字符串和数字0比较时,大概率为true,比如select * from user where username=‘zyong‘ and password=0;,知道用户名就可以登录成功了(password的首字符不为0)。

性能问题在于字符串呵数字比较时,字符串被隐式转换为浮点型(相当于对列进行了运算),这样就无法利用原索引了。

LIKE会将数字类型转换为字符串,可以避免上述问题,比如select * from user where username=‘zyong‘ and password like 0;会将password=0中的0作为字符串‘0‘处理,但如果是select * from user where id like 123456;(或者select * from user where id like ‘123%‘;)则id列(id为int型)会被转换为字符串来与‘123‘进行比较,不会走索引,所以LIKE只建议用在字符串类型上。

参考:https://stackoverflow.com/questions/229179/null-in-mysql-performance-storage

  http://muyue123.blog.sohu.com/146930118.html

  http://www.cnblogs.com/rollenholt/p/5442825.html

  https://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html

时间: 2024-11-05 22:52:26

mysql-优化一的相关文章

Mysql优化(转)

Mysql优化主要通过执行计划,索引,sql语句,调整mysql内部配置 (http://blog.chinaunix.net/uid-11640640-id-3426908.html) 一.优化概述 二.查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 profiling分析查询 2索引及查询优化 三.配置优化 1)      max_connections 2)      back_log 3)      interactive_timeout 4)  

MySQL优化—工欲善其事,必先利其器之EXPLAIN

转自:http://www.cnblogs.com/magialmoon/archive/2013/11/23/3439042.html mysql官方手册关于explain命名的说明文档:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html#explain_select_type 最近慢慢接触MySQL,了解如何优化它也迫在眉睫了,话说工欲善其事,必先利其器.最近我就打算了解下几个优化MySQL中经常用到的工具.今天就简单介绍下

MySQL优化概述

MySQL优化概述 设计: 存储引擎,字段类型,范式 功能: 索引,缓存,分区. 架构: 主从复制,读写分离,负载均衡. 合理SQL: 测试,经验. 存储引擎 Create table tableName () engine=myisam|innodb; 一种用来存储MySQL中对象(记录和索引)的一种特定的结构(文件结构) 存储引擎,处于MySQL服务器的最底层,直接存储数据.导致上层的操作,依赖于存储引擎的选择. Tip:存储引擎就是特定的数据存储格式(方案) Show engines 查看

小菜鸟mysql优化解决方案

根据小菜鸟的个人习惯,自己的编写的一套MYSQL优化方案,感觉还是有点儿菜,望大家谅解,不足之处,请大神们互动! #mysql优化解决方案 #公共参数默认值: max_connections = 151 #同事处理多大连接数,推荐设置最大连接数是上限连接数的80%左右 sort_buffer_size = 2M #查询排序时缓冲区大小,只对order by和group by起作用,可增大此值为16M open_files_limit = 1024 #打开文件数限制,如果show global s

centos mysql 优化 第二十三节课

centos mysql  优化  第二十三节课 f

centos mysql 优化 第二十一节课

centos mysql  优化  第二十一节课 f

centos mysql 优化 第十九节课

centos mysql  优化  第十九节课 f

centos mysql 优化 第十八节课

centos mysql  优化  第十八节课 f

centos mysql 优化 第十二节课

centos mysql  优化  第十二节课 f

网站优化—MySQL优化

MySQL优化 简介 由于页面静态化技术可以实现对动态数据的缓存,但是有的时候还是需要去请求数据库.所以对数据库的优化也是不可缺少的. 优化思路 设计:存储引擎,字段,范式 自身:索引,自身的缓存 架构:读写分离 ? 存储引擎: MyISAM和InnoDB之间的对比.当然需要知道MySQL除了这两种存储引擎还有其他的存储引擎(memory存储引擎). MySQL在5.5版本之后默认的存储引擎为InnoDB 在面试的过程中,只要说出MyISAM和InnoDB的区别即可 ? 字段选择: 合适即好,能