回 帖 发 新 帖 刷新版面

主题:[讨论]如何提高SQL查询的执行效率

各位大虾大家好,初来乍到,还请大家多多指教,我是学习网络工程师专业的,现在将我所学的简单有关数据库的知识于大家一起分享,希望我们可以互相学习,谢谢大家,顺便问语句[url=http://www.gobenet.net.cn]网络工程师待遇[/url]怎么样?希望大家能为我提供一些相关技术,谢谢!
索引介绍和各种索引解释以及创建语句
一、索引介绍
1、普通索引
  普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHEREcolumn=)或排序条件(ORDERBYcolumn)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。
2、唯一索引
  普通索引允许被索引的数据列包含重复的值。比如说,因为人有可能同名,所以同一个姓名在同一个“员工个人资料”数据表里可能出现两次或更多次。
  如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。这么做的好处:一是简化了MySQL对这个索引的管理工作,这个索引也因此而变得更有效率;二是MySQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,MySQL将拒绝插入那条新记录。也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。
3、主索引
  在前面已经反复多次强调过:必须为主键字段创建一个索引,这个索引就是所谓的“主索引”。主索引与唯一索引的唯一区别是:前者在定义时使用的关键字是PRIMARY而不是UNIQUE。
4、外键索引
  如果为某个外键字段定义了一个外键约束条件,MySQL就会定义一个内部索引来帮助自己以最有效率的方式去管理和使用外键约束条件。
5、复合索引
  索引可以覆盖多个数据列,如像INDEX(columnA,columnB)索引。这种索引的特点是MySQL可以有选择地使用一个这样的索引。如果查询操作只需要用到columnA数据列上的一个索引,就可以使用复合索引INDEX(columnA,columnB)。不过,这种用法仅适用于在复合索引中排列在前的数据列组合。比如说,INDEX(A,B,C)可以当做A或(A,B)的索引来使用,但不能当做B、C或(B,C)的索引来使用。
6、索引的长度
  在为CHAR和VARCHAR类型的数据列定义索引时,可以把索引的长度限制为一个给定的字符个数(这个数字必须小于这个字段所允许的最大字符个数)。这么做的好处是可以生成一个尺寸比较小、检索速度却比较快的索引文件。在绝大多数应用里,数据库中的字符串数据大都以各种各样的名字为主,把索引的长度设置为10~15个字符已经足以把搜索范围缩小到很少的几条数据记录了。在为BLOB和TEXT类型的数据列创建索引时,必须对索引的长度做出限制;MySQL所允许的最大索引全文索引文本字段上的普通索引只能加快对出现在字段内容最前面的字符串(也就是字段内容开头的字符)进行检索操作。如果字段里存放的是由几个、甚至是多个单词构成的较大段文字,普通索引就没什么作用了。这种检索往往以的形式出现,这对MySQL来说很复杂,如果需要处理的数据量很大,响应时间就会很长。
  这类场合正是全文索引(full-textindex)可以大显身手的地方。在生成这种类型的索引时,MySQL将把在文本中出现的所有单词创建为一份清单,查询操作将根据这份清单去检索有关的数据记录。全文索引即可以随数据表一同创建,也可以等日后有必要时再使用下面这条命令添加:
  ALTERTABLEtablenameADDFULLTEXT(column1,column2)有了全文索引,就可以用SELECT查询命令去检索那些包含着一个或多个给定单词的数据记录了。下面是这类查询命令的基本语法:
  SELECT*FROMtablename
  WHEREMATCH(column1,column2)AGAINST(‘word1','word2','word3’)
  上面这条命令将把column1和column2字段里有word1、word2和word3的数据记录全部查询出来。
  注解:InnoDB数据表不支持全文索引
二、索引的创建语句:
Sql代码  
1.        1.添加PRIMARY KEY(主键索引)   
2.        mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )   
3.        2.添加UNIQUE(唯一索引)   
4.        mysql>ALTER TABLE `table_name` ADD UNIQUE (`column`)    
5.        3.添加INDEX(普通索引)mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` )   
6.        4.添加FULLTEXT(全文索引)   
7.        mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`)   
8.        5.添加多列索引   
9.        mysql>ALTER TABLE `table_name` ADD INDEX index_name (`column1`, `column2`, `column3` )  
三、在哪些地方加索引:
1、where条件列
2、排序列或者分组列
3、主键本身就是索引,无需再次添加

回复列表 (共2个回复)

沙发

1、操作符号: NOT IN操作符 
此操作是强列推荐不使用的,因为它不能应用表的索引。推荐方案:用NOT EXISTS 或(外连接+判断为空)方案代替 "IS NULL", "<>", "!=", "!>", "!<", "NOT", "NOT EXISTS", "NOT IN", "NOT LIKE", "LIKE '%500'",因为他们不走索引全是表扫描。NOT IN会多次扫描表,使用EXISTS、NOT EXISTS、IN、LEFT OUTER JOIN来替代,特别是左连接,而Exists比IN更快,最慢的是NOT操作. 如果列的值含有空,以前它的索引不起作用,现在2000的优化器能够处理了。相同的是IS NULL,"NOT", "NOT EXISTS", "NOT IN"能优化她,而"<>"等还是不能优化,用不到索引。 

2、注意union和union all的区别。union比union all多做了一步distinct操作。能用union all的情况下尽量不用union。 

3、查询时尽量不要返回不需要的行、列。另外在多表连接查询时,尽量改成连接查询,少用子查询。。 

4、尽量少用视图,它的效率低。对视图操作比直接对表操作慢,可以用存储过程来代替它。特别的是不要用视图嵌套,嵌套视图增加了寻找原始资料的难度。 
我们看视图的本质:它是存放在服务器上的被优化好了的已经产生了查询规划的SQL。对单个表检索数据时,不要使用指向多个表的视图, 
直接从表检索或者仅仅包含这个表的视图上读,否则增加了不必要的开销,查询受到干扰.为了加快视图的查询,MsSQL增加了视图索引的功能。 

5、创建合理的索引,对于插入或者修改比较频繁的表,尽量慎用索引。因为如果表中存在索引,插入和修改时也会引起全表扫描。 
索引一般使用于where后经常用作条件的字段上。 

6、在表中定义字段或者存储过程、函数中定义参数时,将参数的大小设置为合适即可,勿设置太大。这样开销很大。 

7、Between在某些时候比IN速度更快,Between能够更快地根据索引找到范围。用查询优化器可见到差别。 
select * from chineseresume where title in ('男','女') 
Select * from chineseresume where between '男' and '女'是一样的。由于in会在比较多次,所以有时会慢些。 

8、在必要是对全局或者局部临时表创建索引,有时能够提高速度,但不是一定会这样,因为索引也耗费大量的资源。他的创建同是实际表一样。
[url]http://www.beidaqingniao.org[/url]

板凳

1. SQL优化的原则是:将一次操作需要读取的BLOCK数减到最低,即在最短的时间达到最大的数据吞吐量。 
调整不良SQL通常可以从以下几点切入: 
? 检查不良的SQL,考虑其写法是否还有可优化内容 
? 检查子查询 考虑SQL子查询是否可以用简单连接的方式进行重新书写 
? 检查优化索引的使用 
? 考虑数据库的优化器 

2. 避免出现SELECT * FROM table 语句,要明确查出的字段。 

3. 在一个SQL语句中,如果一个where条件过滤的数据库记录越多,定位越准确,则该where条件越应该前移。 

4. 查询时尽可能使用索引覆盖。即对SELECT的字段建立复合索引,这样查询时只进行索引扫描,不读取数据块。 

5. 在判断有无符合条件的记录时建议不要用SELECT COUNT (*)和select top 1 语句。 

6. 使用内层限定原则,在拼写SQL语句时,将查询条件分解、分类,并尽量在SQL语句的最里层进行限定,以减少数据的处理量。 

7. 应绝对避免在order by子句中使用表达式。 

8. 如果需要从关联表读数据,关联的表一般不要超过7个。 

9. 小心使用 IN 和 OR,需要注意In集合中的数据量。建议集合中的数据不超过200个。 

10. <> 用 < 、 > 代替,>用>=代替,<用<=代替,这样可以有效的利用索引。 

[url]http://www.beidaqingniao.org[/url]

我来回复

您尚未登录,请登录后再回复。点此登录或注册