互联网时代的进程越走越深,经常使用MySQL的人也越来越多,关于MySQL的数据库优化指南很多,而关于SQL SERVER的T-SQL优化指南看下来比拟少,近期有学习SQLSERVER的同窗识到SQL SERVER数据库有哪些优化倡导?本文罗列了局部经常出现的优化倡导,详细内容如下:
索引优化:
NULL 值判别防止全表扫描:
eg:关于蕴含 status 列的用户表 Users,防止经常使用 SELECT * FROM Users WHERE status IS NULL,可以在设计表时设置 status 自动值,确保一切用户都有一个形态,而后经常使用 SELECT * FROM Users WHERE status = 0 启动查问。
!= 或 <> 操作符防止全表扫描:
eg:思考一个产品表 Products,假设要查问一切不属于某个特定类别的产品,防止经常使用 SELECT * FROM Products WHERE CategoryID != 5,而是经常使用 SELECT * FROM Products WHERE CategoryID <> 5。
OR 衔接条件防止全表扫描:
eg:关于一个在校生效果表 Grades,假设须要查问得分为 A 或 B 的记载,防止经常使用 SELECT * FROM Grades WHERE Grade = 'A' OR Grade = 'B',而是经常使用 SELECT * FROM Grades WHERE Grade = 'A' UNION ALL SELECT * FROM Grades WHERE Grade = 'B'。
IN 和 NOT IN 防止全表扫描:
eg:思考一个员工表 Employees,假设须要查问属于某个特定部门的员工,防止经常使用 SELECT * FROM Employees WHERE DepartmentID IN (1, 2, 3),而是经常使用 SELECT * FROM Employees WHERE DepartmentID BETWEEN 1 AND 3。
LIKE 查问优化:
eg:在一个文章表 Articles 中,假设须要含糊查问题目蕴含关键词的文章,防止经常使用 SELECT * FROM Articles WHERE Title LIKE '%SQL%',可以思考全文检索或许其余优化方式。
参数经常使用防止全表扫描:
eg:在一个订单表 Orders 中,假设须要依据输入的订单号查问订单信息,防止经常使用 SELECT * FROM Orders WHERE OrderID = @OrderID,可以经常使用强迫索引的方式,如 SELECT * FROM Orders WITH(INDEX(OrderID_Index)) WHERE OrderID = @OrderID。
字段表白式操作防止全表扫描:
eg:在一个商品表 Products 中,假设须要查问多少钱除以2等于100的商品,防止经常使用 SELECT * FROM Products WHERE Price/2 = 100,可以改为 SELECT * FROM Products WHERE Price = 100*2。
字段函数操作防止全表扫描:
eg:在一个员工表 Employees 中,假设须要查问名字以"Smith"扫尾的员工,防止经常使用 SELECT * FROM Employees WHERE LEFT(LastName, 5) = 'Smith',可以改为 SELECT * FROM Employees WHERE LastName LIKE 'Smith%'。
不要在“=”左边启动函数、算术运算:
eg:在一个库存表 Inventory 中,防止经常使用 SELECT * FROM Inventory WHERE YEAR(StockDate) = 2023,而是经常使用 SELECT * FROM Inventory WHERE StockDate >= '2023-01-01' AND StockDate < '2024-01-01'。
索引字段顺序经常使用防止全表扫描:
eg:在一个订单表 Orders 中,假设有复合索引 (CustomerID, OrderDate),查问时应该先经常使用 CustomerID,如 SELECT * FROM Orders WHERE CustomerID = @CustomerIDAND OrderDate BETWEEN @StartDate AND @EndDate。
防止写没无心义的查问:
eg:不倡导经常使用 SELECT col1, col2 INTO #t FROM t WHERE 1 = 0,可以改为明白创立表结构并经常使用 CREATE TABLE #t (...)。
经常使用 EXISTS 替代 IN:
eg:在一个产品表 Products 中,防止经常使用 SELECT * FROM Products WHERE ProductID IN (SELECT ProductID FROM DiscontinuedProducts),可以改为 SELECT * FROM Products WHERE EXISTS (SELECT 1 FROM DiscontinuedProducts WHERE ProductID = Products.ProductID)。
索引不必定对一切查问有效:
eg:在一共性别字段 Gender 简直平均散布的表中,对 Gender 建设索引或许不会提高查问效率。
索引数量审慎选用:
eg:在一个订单表 Orders 中,不宜过多地在每个列上建设索引,须要依据查问和降级的详细需求启动掂量。
降级 clustered 索引数据列审慎操作:
eg:在一个用户表 Users 中,假设频繁降级用户姓名,思考能否将姓名列设为非汇集索引,以防止整个表记载顺序调整。
经常使用数字型字段:
eg:在一个在校生效果表 Grades 中,假设考试效果以整数方式示意,经常使用整数型字段而非字符型字段。
经常使用 VARCHAR/NVARCHAR:
eg:在一个文章表 Articles 中,假设存储文章内容,经常使用 VARCHAR(MAX) 而非 TEXT。
防止经常使用 SELECT *:
eg:在一个员工表 Employees 中,防止经常使用 SELECT * FROM Employees,而是明白指定须要的列,如 SELECT EmployeeID, FirstName, LastName FROM Employees。
经常使用表变量替代暂时表:
eg:在一个小型数据集的状况下,可以经常使用表变量而不是创立暂时表来存储两边结果。例如,经常使用表变量替代以下的暂时表:
-- 不介绍CREATE TABLE #TempResults (ID INT,Name VARCHAR(255),...-- 介绍DECLARE @TempResults TABLE (ID INT,Name VARCHAR(255),...);
防止频繁创立和删除暂时表:
eg:在一个存储环节中,假设须要屡次经常使用相反的暂时表,不要在每次经常使用时都创立和删除,而是在存储环节的扫尾创立一次性,最后删除。
eg:在一个复杂的查问中,假设须要屡次援用两边结果,可以思考经常使用暂时表。但应留意不要滥用,确保暂时表的经常使用是必要的。
选用适宜的暂时表创立方式:
eg:在须要一次性性拔出少量数据的状况下,可以经常使用 SELECT INTO 替代 CREATE TABLE 和 INSERT 的两步操作,以缩小日志记载。
不介绍CREATE TABLE # INT INSERT INTO # ID FROM 介绍 ID INTO #FROM
eg:在存储环节或脚本的最后,确保显式删除一切创立的暂时表,以监禁系统表资源。
不介绍DROP TABLE # 介绍TRUNCATE TABLE #DROP TABLE #
eg:在一个订单表 Orders 中,防止经常使用游标来逐行处置数据,可以思考经常使用汇合操作或许其余优化方法。
基于集的方法替代游标或暂时表:
eg:在须要对少量数据启动操作时,尽量寻觅基于集的处置方案,以防止经常使用游标或暂时表。例如,经常使用窗口函数或联接来处置数据。
eg:在存储环节中经常使用 SET NOCOUNT ON 和 SET NOCOUNT OFF,以缩小向客户端发送 DONE_IN_PROC 信息,提高性能。
-- 存储环节扫尾SET NOCOUNT ON;-- 存储环节开头SET NOCOUNT OFF;
eg:在一个银行买卖表 Transactions 中,防止在一个事务中处置过多的买卖记载,以提高系统并发才干。
防止向客户端前往大数据量:
eg:在一个日志表 Logs 中,假设查问或许前往少量的日志记载,应该审查客户端能否真的须要这么少数据,思考分页或其余方式缩小前往的数据量。
经常使用EXPLAIN或Show Execution Plan剖析查问口头方案,发现潜在疑问。
相熟其余数据库的同窗应该也能对比出,很少数据库的优化阅历是相通的,所以在学习其余数据库的时刻可以自创已把握的阅历去对比学习,这样学习起来也会事倍功半。