0%

Sql相关知识点总结

本文整理了一些常见的sql知识点(包括博客链接整理)

如何查找MySQL中查询慢的SQL语句

如何查找MySQL中查询慢的SQL语句

慢查询的原因

  • 没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)
  • I/O吞吐量小,形成了瓶颈效应。
  • 没有创建计算列导致查询不优化。
  • 内存不足
  • 网络速度慢
  • 查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)
  • 锁或者死锁(这也是查询慢最常见的问题,是程序设计的缺陷)
  • sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。
  • 返回了不必要的行和列
  • 查询语句不好,没有优化

慢查询的解决办法

1.把数据、日志、索引放到不同的I/O设备上,增加读取速度,以前可以将Tempdb应放在RAID0上,SQL2000不在支持。数据量(尺寸)越大,提高I/O越重要
2.纵向、横向分割表,减少表的尺寸
3.升级硬件
4.根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。
5.提高网速;
6.扩大服务器的内存;
7.增加服务器CPU个数;但是必须明白并行处理串行处理更需要资源例如内存。
8.如果是使用like进行查询的话,简单的使用index是不行的,但是全文索引,耗空间。 like ‘a%’ 使用索引 ,like ‘%a’ 不使用索引用 like ‘%a%’ 查询时,查询耗时和字段值总长度成正比,所以不能用CHAR类型,而是VARCHAR。对于字段的值很长的建全文索引。

索引失效

1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
2.对于多列索引,不是使用的第一部分(第一个),则不会使用索引
3.like查询是以%开头
4..如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引
6.没有查询条件,或者查询条件没有建立索引
7.查询的数量是大表的大部分,应该是30%以上
8.查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,,/,! 等) 错误的例子:select from test where id-1=9; 正确的例子:select * from test where id=10;
9.not in ,not exist
10.B-tree索引 is null不会走,is not null会走,位图索引 is null,is not null 都会走

sql优化

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,创建表时NULL是默认值,但大多数时候应该使用NOT NULL,或者使用一个特殊的值,如0,-1作为默 认值。
3.应尽量避免在 where 子句中使用!=或<>操作符, MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。
4.应尽量避免在 where 子句中使用 or 来连接条件, 否则将导致引擎放弃使用索引而进行全表扫描, 可以 使用UNION合并查询: select id from t where num=10 union all select id from t where num=20
5.in 和 not in 也要慎用,否则会导致全表扫描,对于连续的数值,能用 between 就不要用 in 了:Select id from t where num between 1 and 3
6.like查询避免是以%开头
7.如果在 where 子句中使用参数,也会导致全表扫描。
8.应尽量避免在 where 子句中对字段进行表达式操作,应尽量避免在where子句中对字段进行函数操作
9.很多时候用 exists 代替 in 是一个好的选择,用select num from a where exists(select 1 from b where num=a.num)替换select num from a where num in(select num from b)
10.索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,一个表的索引数最好不要超过6个。
11.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。
12.尽可能的使用 varchar/nvarchar 代替 char/nchar , 因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
13.最好不要使用select from t返回所有,,用具体的字段列表代替*,不要返回用不到的任何字段。
14.尽量避免向客户端返回大数据量
15.使用表的别名(Alias):当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。
16.使用“临时表”暂存中间结果。
17.常见的简化规则如下:不要有超过5个以上的表连接(JOIN),考虑使用临时表或表变量存放中间结果。
18.将需要查询的结果预先计算好放在表中,查询的时候再Select。
19.尽量使用“>=”,不要使用“>”。
20.下列SQL条件语句中的列都建有恰当的索引,但执行速度却非常慢:

1
2
3
SELECT * FROM record WHERE substrINg(card_no,1,4)=’5378’ (13秒)
SELECT * FROM record WHERE amount/30< 100011秒)
SELECT * FROM record WHERE convert(char(10),date,112)=’19991201’ (10秒)

分析:
WHERE子句中对列的任何操作结果都是在SQL运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被SQL优化器优化,使用索引,避免表搜索,因此将SQL重写成下面这样:

1
2
3
SELECT * FROM record WHERE card_no like5378%’ (< 1秒)
SELECT * FROM record WHERE amount< 1000\*30 (< 1秒)
SELECT * FROM record WHERE date= ‘1999/12/01’ (< 1秒)

21.当有一批处理的插入或更新时,用批量插入或批量更新,绝不会一条条记录的去更新
22.当只要一行数据时使用 LIMIT 1
23.选择表合适存储引擎:myisam: 应用时以读和插入操作为主,只有少量的更新和删除,并且对事务的完整性,并发性要求不是很高的。Innodb: 事务处理,以及并发条件下要求数据的一致性。除了插入和查询外,包括很多的更新和删除。
24.任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边