1前言

Sql 语句调优对应用性能非常重要,看了几篇文章,总结了一下数据库优化的方法。

2 数据库 Sql 优化

1 对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

关于索引请看我的这篇文章 https://www.cnblogs.com/mhq-martin/p/8184328.html

SELECT sid
FROM Student
WHERE Gradeid=

执行时间:17.609s (多次执行,在17s左右徘徊)

优化后:给Gradeid字段添加索引后

执行时间为:11.377s(多次执行,在11s左右徘徊)

备注:我们一般在什么字段上建索引?

这是一个非常复杂的话题,需要对业务及数据充分分析后再能得出结果。主键及外键通常都要有索引,其它需要建索引的字段应满足以下条件:

a、字段出现在查询条件中,并且查询条件可以使用索引;

b、语句执行频率高,一天会有几千次以上;

c、通过字段条件可筛选的记录集很小,那数据筛选比例是多少才适合?

这个没有固定值,需要根据表数据量来评估,以下是经验公式,可用于快速评估:

小表(记录数小于10000行的表):筛选比例<10%;

大表:(筛选返回记录数)<(表总记录数*单条记录长度)/10000/16

单条记录长度≈字段平均内容长度之和+字段数*2

2 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。

select sid from Student where num is null

最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.

备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。

可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

select sid from Student where num = 0

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

4 应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描。(用union all 代替)

GRADE_ID字段有索引,QUESTION_TYPE没索引

SELECT sid
FROM Student
WHERE Gradeid=
OR Gradetype=

优化方案:

SELECT sid
FROM Student
WHERE Gradeid=
union all
SELECT sid
FROM Student
WHERE Gradetype=

通过union all 方式,把有索引字段和非索引字段分开。索引字段就有效果了。

5 in 和 not in 也要慎用,否则会导致全表扫描

注:在mysql数据库中where 子句中对索引字段使用 in 和 not in操作符,引擎不会放弃使用索引。

注:在mysql数据库中where 子句中对不是索引字段使用 in 和 not in操作符,会导致全表扫描。

6 负向查询不能使用索引

select name from user where id not in (1,3,4);

应该修改为:

select name from user where id in (2,5,6);

7 前导模糊查询不能使用索引

如:

select name from user where name like '%zhangsan'

非前导则可以:

select name from user where name like 'zhangsan%'

建议可以考虑使用 Lucene 等全文索引工具来代替频繁的模糊查询。

8 数据区分不明显的不建议创建索引

如 user 表中的性别字段,可以明显区分的才建议创建索引,如身份证等字段。

9 在字段上进行计算不能命中索引

select name from user where FROM_UNIXTIME(create_time) < CURDATE();

应该修改为:

select name from user where create_time < FROM_UNIXTIME(CURDATE());

10 最左前缀问题

如果给 user 表中的 username pwd 字段创建了复合索引那么使用以下SQL 都是可以命中索引:

但是使用

select username from user where pwd ='axsedf1sd'

是不能命中索引的。

11 如果明确知道只有一条记录返回

select name from user where username='zhangsan' limit 1

可以提高效率,可以让数据库停止游标移动。

12 不要让数据库帮我们做强制类型转换

select name from user where telno=18722222222

这样虽然可以查出数据,但是会导致全表扫描。

需要修改为

select name from user where telno='18722222222'

13 如果需要进行 join 的字段两表的字段类型要相同

不然也不会命中索引。

Sql 调优总结的更多相关文章

  1. SQL调优常用方法

    在使用DBMS时经常对系统的性能有非常高的要求:不能占用过多的系统内存和 CPU资源.要尽可能快的完成的数据库操作.要有尽可能高的系统吞吐量.如果系统开发出来不能满足要求的所有性能指标,则必须对系统进 ...

  2. SQL调优

    # 问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...

  3. 读《程序员的SQL金典》[4]--SQL调优

    一.SQL注入 如果程序中采用sql拼接的方式书写代码,那么很可能存在SQL注入漏洞.避免的方式有两种: 1. 对于用户输入过滤敏感字母: 2. 参数化SQL(推荐). 二.索引 ①索引分类 聚簇索引 ...

  4. [SQL SERVER系列]读书笔记之SQL注入漏洞和SQL调优

    最近读了程序员的SQL金典这本书,觉得里面的SQL注入漏洞和SQL调优总结得不错,下面简单讨论下SQL注入漏洞和SQL调优. 1. SQL注入漏洞 由于“'1'='1'”这个表达式永远返回 true, ...

  5. SQL调优日志--内存问题

    SQL调优日志--内存问题排查入门篇   概述 很多系统的性能问题,是由内存导致的.内存不够会导致页面频繁换入换出,IO队列高,进而影响数据库整体性能. 排查 内存对数据库性能非常重要.那么我当出现问 ...

  6. 读书笔记之SQL注入漏洞和SQL调优

    原文:读书笔记之SQL注入漏洞和SQL调优 最近读了程序员的SQL金典这本书,觉得里面的SQL注入漏洞和SQL调优总结得不错,下面简单讨论下SQL注入漏洞和SQL调优. 1. SQL注入漏洞 由于“' ...

  7. Oracle SQL 调优健康检查脚本

    Oracle SQL 调优健康检查脚本 我们关注数据库系统的性能,进行数据库调优的主要工作就是进行SQL的优化.良好的数据架构设计.配合应用系统中间件和写一手漂亮的SQL,是未来系统上线后不出现致命性 ...

  8. Script:SQL调优健康检查脚本

    Script:SQL调优健康检查脚本 http://www.askmaclean.com/archives/sql-tuning-health-check-script.html 以下脚本可以用于收集 ...

  9. SQL注入漏洞和SQL调优SQL注入漏洞和SQL调优

    SQL注入漏洞和SQL调优 最近读了程序员的SQL金典这本书,觉得里面的SQL注入漏洞和SQL调优总结得不错,下面简单讨论下SQL注入漏洞和SQL调优. 1. SQL注入漏洞 由于“'1'='1'”这 ...

  10. 记一次SQL调优/优化(SQL tuning)——性能大幅提升千倍以上

    好久不写东西了,一直忙于各种杂事儿,恰巧昨天有个用户研发问到我一个SQL调优的问题,说性能太差,希望我能给调优下,最近有些懒,可能和最近太忙有关系,本来打算问问现在的情况,如果差不多就不调了,那哥们儿 ...

随机推荐

  1. (后端)mybatis中使用Java8的日期LocalDate、LocalDateTime

    原文地址:https://blog.csdn.net/weixin_38553453/article/details/75050632 MyBatis的型处理器是属性“createdtime参数映射为 ...

  2. Python 套接字socketserver网络编程

    为什么使用socketserver 虽然Python内置的socket和threading模块能实现简单的多线程服务器,在非正式环境,随便用用还是可以的,但是如果要在生产环境中使用,那是万万不够的. ...

  3. CsQuery中文编码乱码问题

    一.问题描述 InnerHTML 中文显示为Модель 二.解决方法 在初始化CQ对象前,先设置执行以下语句: CsQuery.Config.HtmlEncoder = CsQuery.HtmlEn ...

  4. LeetCode题解之Squares of a Sorted Array

    1.题目描述 2.问题分析 使用过两个计数器. 3.代码 class Solution { public: vector<int> sortedSquares(vector<int& ...

  5. [20170612]FOR ALL COLUMNS SIZE repeat(11g).txt

    [20170612]FOR ALL COLUMNS SIZE repeat(11g).txt --//昨天看了https://jonathanlewis.wordpress.com/2017/06/0 ...

  6. jquery hover事件只触发一次动画

    最近工作时遇到个关于动画的问题,如下: $("div").hover( function() { $(this).animate({"margin-top":& ...

  7. js获取地址栏中的数据

    window.location.href:设置或获取整个 URL 为字符串window.location.pathname:设置或获取对象指定的文件名或路径window.location.search ...

  8. Java中 try--catch-- finally、throw、throws 的用法

    一.try {..} catch {..}finally {..}用法 try { 执行的代码,其中可能有异常.一旦发现异常,则立即跳到catch执行.否则不会执行catch里面的内容 } catch ...

  9. distribution 分发数据库 灾难恢复 备份恢复

    参考: http://www.sqlservercentral.com/articles/Replication/117265/ 前提:     准备一台电脑,主机名和以前的分发数据库一致.并且安装s ...

  10. C#获取日期的星期名称

    private string GetWeekName(DayOfWeek week) { string weekName = ""; switch (week) { case Da ...