一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Sql Server - SQL Server 百萬數據查詢優化技巧三十則

SQL Server 百萬數據查詢優化技巧三十則

2023-11-29 07:00未知服務器之家 Sql Server

互聯網時代的進程越走越深,使用MySQL的人也越來越多,關于MySQL的數據庫優化指南很多,而關于SQL SERVER的T-SQL優化指南看上去比較少,近期有學習SQLSERVER的同學問到SQL SERVER數據庫有哪些優化建議?本文列舉了部分常見的優化建議

SQL Server 百萬數據查詢優化技巧三十則

互聯網時代的進程越走越深,使用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、結語

 熟悉其他數據庫的同學應該也能對比出,很多數據庫的優化經驗是相通的,所以在學習其他數據庫的時候可以借鑒已掌握的經驗去對比學習,這樣學習起來也會事半功倍。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色狠狠色狠狠综合天天 | 狠狠操社区 | 欧美日本道免费一区二区三区 | 亚洲免费在线看 | 日本在线播放视频 | 美女草b | 成人啪精品视频免费网站 | 丁香六月色 | 精品人人视屏 | 国产一区二区三区在线看 | 极品丝袜老师h系列全文阅读 | 青草网在线观看 | 欧美综合精品一区二区三区 | 全黄一级裸片视频免费 | 欧美一区二区三区成人看不卡 | 国内精品伊人久久大香线焦 | 狠狠操社区 | 日日精品| 久久久精品日本一区二区三区 | 精品综合| www黄| 免费网站看v片在线香蕉 | 精品亚洲一区二区三区在线播放 | 香蕉精品国产高清自在自线 | 国产欧美国产综合第一区 | 九九精品视频在线免费观看 | 男人日女人的逼视频 | 91高清在线视频 | 性xxxx18学生第一次出血 | 成人久久18免费网站 | 大陆国产vs国产对白 | 性欧美xxxxx护士另类 | gayrb漫画免费入口 | 亚洲国产综合久久久无码色伦 | 亲爱的客栈第二季免费观看完整版 | 精品视频在线播放 | 亚洲第一人黄所 | 亚洲 综合 欧美在线视频 | 天天躁天天碰天天看 | 国产一卡2卡3卡四卡精品网站 | 国产欧美视频一区二区三区 |