MYSQL性能调优(二)

MYSQL性能调优(二)

  1. order by (在大数量下排序是大坑,需要额外注意)

1) order by的字段改到一种表、不要夸表(设计表结构时需注意这一点)

2) order by 字段建索引、多个字段时建联合索引(联合索引的字段顺序要与order by 的字段顺序一致)

3) order by中字段中联合索引的所有字段DESC或ASC要统一,否则索引不起作用

4)不要对TEXT字段或者CLOB字段进行排序

  1. 避免在索引列上使用计算
(低效)select ... from [dept] where [sal]*12>25000; 
(高效)select ... from [dept] where [sal]>25000/12;
  1. 不同类型的索引效能是不一样的,应尽可能先使用效能高的

1)数字类型的索引查找效率高于字符串类型,定长字符串char、nchar的索引效率高于变长字符串varchar、nvarchar的索引。

   (低效)select ... from tableName where username='张三' and age>=21
   (高效)select ... from tableName where age>=21 and username='张三'
  1. is null或is not null操作

​ 判断字段是否为空一般是不会应用索引的,因为索引不索引空值。不能用null作索引,任何包含null值的列都将不会被包含在索引中。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。任何在where子句中使用is null或is not null的语句优化器都不允许使用索引。

推荐方案:用其他相同功能的操作运算代替,如:a is not null改为a>0或a>’'等。

  1. <及>操作

​ 大于或小于一般情况不用调整,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化。如一个表有100万记录,那么执行**>2与>=3**的效果就有很大区别了。

(低效)select * from [emp] where [deptno]>2;
(高效)select * from [emp] where [deptno]>=3;
  1. where后面的条件顺序影响 (数字好于字符串)

  2. like操作
    like操作可以应用通配符查询,里面的通配符组合可能达到几乎是任意的查询,但是如果用不好则会产生性能上的问题,如lide ‘%5400%’ 这种查询不会引用索引,而like ‘X5400%’ 则会引用范围索引。

  3. 用union替换or(适用于索引列)

    (低效)select loc_id,loc_desc,begion from location where loc_id=10 or begion='MELBOURNE'; 
    (高效)select loc_id,loc_desc,begion from location where loc_id=10
                union
               select loc_id,loc_desc_begion from location where begion='MELBOURNE'; 
    
  4. 优化group by : 不要使用having
    提高group by语句的效率,可以通过将不需要的记录在group by之前过滤掉。

    (低效)select [job],avg([sal]) from [emp] group by [job] having job='PRESIDENT' or job='MANAGER'; 
    (高效)select [job],avg([sal]) from [emp] where [job]='PRESIDENT' or job='MANAGER' group by [job];
    
  5. 如果使用了in或or等时发现查询没有走索引,使用显式申明指定索引: SELECT * FROM PersonMember (INDEX = IX_Title) WHERE processid IN (‘男’,‘女’)。

  6. 分析select emp_name form employee where salary>3000 在此语句中若salary是Float类型的,则优化器对其进行优化为Convert(float,3000),因为3000是个整数,我们应在编程时使用3000.0而不要等运行时让DBMS进行转化。同样字符和整型数据的转换。 (减少优化器自己优化的时间)

  7. 应尽量避免在 where 子句中使用!=或<>操作符,否则将放弃使用索引而进行全表扫描。

  8. 、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段 sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。 (会产生二次查询的情况:你从索引中拿到的只是地址,要想真正访问到数据还是要对表进行一次IO:也是看情况的,主要看你的SQL怎么去用,怎么去写 )

    总结

    • *索引并不是越多越好,索引提交了select效率,但是降低了insert和update的效率。一个表的索引数最好不要超过6个。

    • 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。因为引擎在处理查询和连接时会逐个比较字符串中每个字符,而对于数字型而言只需要比较一次就够了。

    • 任何地方都不要使用select ,用具体的字段列表代替,不要返回用不到的字段。

    • 尽可能使用varchar/nvarchar代替char/nchar,因为首先变长字段存储空间小,可以节省存储空间;其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

    • 采用函数处理的字段不能利用索引

    • 1)索引本身是以文件的形式存放在硬盘,需要的时候才加载至内存,所以添加索引会增加磁盘的开销;

      2)写数据:需要更新索引,对数据库是个很大的开销,降低表更新、添加和删除的速度

      PS:索引的选择性较低,所谓索引的选择性,是指不重复的索引值与表记录数的比值,取值范围(0-1)。选择性越高,索引的价值越大。

    • 创建组合索引时应该将最常用作限制条件的列放在最左边,依次递减。

    • 三剑客:修改配置文件,打开MYSQL慢查询语句存储(mysqldumpslow --help)、explain分析、profiling分析查询(可以更准确的SQL执行消耗系统资源的信息)

猜你喜欢

转载自blog.csdn.net/oraclejet/article/details/83478982