以下的SQL语句以Northwind为例

1、不要再where子句中"="的左侧使用函数和表达式,因为系统无法应用函数或表达式中的索引

SELECT * FROM Customers WHERE Cast(CustomerID AS VARCHAR(20))='1' --Clustered Index Scan 全表扫描
SELECT * FROM Customers WHERE CustomerID ='1' --Clustered Index Seek 索引扫描

2、只返回必要的行或列
2.1 减少I/O次数
2.2 减少加载到内存的数据量

3、关于组合索引(待定)
组合索引中的顺序很重要,当查询语句中的列只能与组合索引中的第1列相匹配时,才能在查询中应用此索引

4、Distinct语句的使用原则
尽量少用,因为数据库引擎需要花费大量的时间对所有字段进行比较,过滤掉重复的记录,因此影响了查询的效率
字段较少时,可适当采用;较多时,不宜采用

5、Union语句
Union必须满足以下要求:
1、所有select语句的列数必须相同
2、所有select语句中对应列的数据类型必须兼容

执行包含Union的查询语句的过程如下:
1、依次执行所有select语句
2、将所有select语句的结果集合并为一个结果集
3、对结果集进行排序,并过滤掉重复的记录(由于需要第3步的操作,导致联合查询效率很低)
可使用union all,不用排序和过滤重复记录,效率高

6、使用存储过程
数据库引擎可以在创建存储过程时对其进行分析和优化,并可在首次执行该过程后使用该过程的内存中版本。
相对来说,每次运行sql语句时,都要从客户端重复发送,并且在sqlserver每次执行这些语句时,对其进行编译和优化。

7、如果需要多次对一个数据量非常大的表中一部分数据进行查询操作,可以将这部分数据放在临时表中,然后对临时表进行操作。

8、模糊匹配符%和索引的关系
假定有一个表Good,主键为聚集索引,类型为nvarchar(50)
SELECT * FROM Goods AS g WHERE g.GoodsName LIKE '%商品1' --Clustered Index Scan 全表扫描
SELECT * FROM Goods AS g WHERE g.GoodsName LIKE '商%品1' --Clustered Index Seek 索引扫描
SELECT * FROM Goods AS g WHERE g.GoodsName LIKE '商品1%' --Clustered Index Seek 索引扫描
结论:通配符%放在中间和后面会走索引,放在前面不会

9、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
SELECT * FROM Employees AS e WHERE e.EmployeeID =1 --走聚集索引
SELECT * FROM Employees AS e WHERE e.EmployeeID IS NULL --Constanct Scan

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

11、在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

12、不用SELECT *查询

1、SELECT * 会产生额外的IO,消耗额外的带宽资源。当数据库有大量这类SQL,就会产生量变到质变。慢慢影响整个数据库的性能。

2、SELECT *会返回大量的数据,并占用内存空间,影响操作速度

3、SELECT *可能还会导致不走索引(同样的sql语句,一个select *,一个select具体字段)

DROP TABLE TEST;
SELECT * INTO TEST FROM sys.objects SELECT CREATE_DATE, TYPE FROM TEST
WHERE CREATE_DATE >='2013-07-09 00:00'
AND CREATE_DATE <='2014-04-30 00:00'
AND TYPE='S' SELECT * FROM TEST
WHERE CREATE_DATE >='2013-07-09 00:00'
AND CREATE_DATE <='2014-04-30 00:00'
AND TYPE='S'

13、索引的列数对扫描的影响

DROP TABLE TEST;
SELECT * INTO TEST FROM sys.objects --初始化表数据 DROP INDEX IDX_TEST_N1 ON TEST --只对默写字段建索引,全表扫描比索引扫描开销小,查询不走索引,走全表扫描(Table Scan)
CREATE INDEX IDX_TEST_N1 ON TEST(CREATE_DATE, TYPE) --建所有列的索引时,下面的查询会走索引(Index Seek)
CREATE NONCLUSTERED INDEX IDX_TEST_N1
ON [dbo].[TEST] ([type],[create_date])
INCLUDE ([name],[object_id],[principal_id],[schema_id],[parent_object_id],[type_desc],[modify_date],[is_ms_shipped],[is_published],[is_schema_published])
GO SET SHOWPLAN_ALL ON
GO
SELECT * FROM TEST
WHERE CREATE_DATE >='2013-04-09 00:00'
AND CREATE_DATE <='2014-04-30 00:00'
AND TYPE='S'
GO
SET SHOWPLAN_ALL OFF;
GO

14、为什么不走索引(查询条件中LastName列为非聚集索引)

 --批执行计划(Ctrl+L),可以查看各条语句的【查询开销】
--上条语句不走LastName索引,而是走聚集扫描,是因为走索引I/O开销较大,因为数据量较小;如果数据量增加到较多时,如1k以上,则可能走索引
SELECT * FROM Employees AS e WHERE e.LastName='Davolio' -- SELECT * FROM Employees AS e WITH(INDEX=LastName) WHERE e.LastName='Davolio'
--批执行计划(Ctrl+L)

走不走索引的影响因素

--1、查询的数据大小
--2、数据的分布
--3、I/O开销

最新文章

  1. HDU 4569 Special equations(取模)
  2. 使用python的redis 实现消息的pub/sub功能
  3. Big Data, MapReduce, Hadoop, and Spark with Python
  4. 树形DP水题杂记
  5. JavaScript(1)
  6. Container With Most Water
  7. TCP/IP协议原理与应用笔记21:路由选择的方法
  8. 如何在Android中使用OpenCV
  9. TCP洪水攻击(SYN Flood)的诊断和处理
  10. css实现小三角效果
  11. 浅谈C/C++引用和指针的联系和区别
  12. 最小点集覆盖=最大匹配&lt;二分图&gt;/证明
  13. linux各类压缩解压命令大全
  14. 比特币区块结构Merkle树及简单支付验证分析
  15. vue2.0 页面A跳转到页面B,B页面停留在A页面的滚动位置的解决方法
  16. Linux 开启和关闭 Ping 操作
  17. 外网訪问XAMPP失败 解决方式 XAMPP1.8.3
  18. 判断页面是否添加了W3C声明
  19. 自定义sql server 聚合涵数
  20. 【排序算法】冒泡排序(Bubble Sort)

热门文章

  1. 查看Linux系统版本信息
  2. WWDC————苹果全球开发者大会
  3. winform之回车执行某个按钮 以及Esc执行某个按钮
  4. Winform开发常用控件之Checkbox和CheckedListBox
  5. Mysql varchar大小长度问题介绍
  6. jquery学习笔记(4)--实现table隔行变色以及单选框选中
  7. 第七章 管理类型(In .net4.5) 之 使用类型
  8. python 上下文管理器
  9. Resource is out of sync with the file system
  10. 深度神经网络DNN的多GPU数据并行框架 及其在语音识别的应用