好域名做网站,wordpress 探针,网站建设概括,叫外包公司做网站不肯给源代码的点击上方蓝字关注我 互联网时代的进程越走越深#xff0c;使用MySQL的人也越来越多#xff0c;关于MySQL的数据库优化指南很多#xff0c;而关于SQL SERVER的T-SQL优化指南看上去比较少#xff0c;近期有学习SQLSERVER的同学问到SQL SERVER数据库有哪些优化建议#xff1f… 点击上方蓝字关注我 互联网时代的进程越走越深使用MySQL的人也越来越多关于MySQL的数据库优化指南很多而关于SQL SERVER的T-SQL优化指南看上去比较少近期有学习SQLSERVER的同学问到SQL SERVER数据库有哪些优化建议本文列举了部分常见的优化建议具体内容如下 1. 优化建议 索引优化eg考虑一个订单表 Orders其中有列 OrderDate 和 CustomerID。如果经常需要按订单日期范围和顾客ID进行查询可以在这两列上建立复合索引以提高查询性能。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 CustomerID AND 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 #TempTable (ID INT,Name VARCHAR(255),...
);INSERT INTO #TempTable
SELECT ID, Name, ...
FROM SomeTable;-- 推荐
SELECT ID, Name, ...
INTO #TempTable
FROM SomeTable; 显式删除临时表 eg在存储过程或脚本的最后确保显式删除所有创建的临时表以释放系统表资源。 -- 不推荐
DROP TABLE #TempTable;-- 推荐
TRUNCATE TABLE #TempTable;
DROP TABLE #TempTable; 避免使用游标 eg在一个订单表 Orders 中避免使用游标来逐行处理数据可以考虑使用集合操作或者其他优化方法。 基于集的方法替代游标或临时表 eg在需要对大量数据进行操作时尽量寻找基于集的解决方案以避免使用游标或临时表。例如使用窗口函数或联接来处理数据。 存储过程中使用 SET NOCOUNT ON/OFF eg在存储过程中使用 SET NOCOUNT ON 和 SET NOCOUNT OFF以减少向客户端发送 DONE_IN_PROC 消息提高性能。 -- 存储过程开头
SET NOCOUNT ON;-- 存储过程结尾
SET NOCOUNT OFF; 避免大事务操作 eg在一个银行交易表 Transactions 中避免在一个事务中处理过多的交易记录以提高系统并发能力。 避免向客户端返回大数据量 eg在一个日志表 Logs 中如果查询可能返回大量的日志记录应该审查客户端是否真的需要这么多数据考虑分页或其他方式减少返回的数据量。 SQL Server执行计划掌握 使用EXPLAIN或Show Execution Plan分析查询执行计划发现潜在问题。 2. 结语 熟悉其他数据库的同学应该也能对比出很多数据库的优化经验是相通的所以在学习其他数据库的时候可以借鉴已掌握的经验去对比学习这样学习起来也会事半功倍。 往期精彩回顾 1. MySQL高可用之MHA集群部署 2. mysql8.0新增用户及加密规则修改的那些事 3. 比hive快10倍的大数据查询利器-- presto 4. 监控利器出鞘PrometheusGrafana监控MySQL、Redis数据库 5. PostgreSQL主从复制--物理复制 6. MySQL传统点位复制在线转为GTID模式复制 7. MySQL敏感数据加密及解密 8. MySQL数据备份及还原一 9. MySQL数据备份及还原二 扫码关注