SQL Server 查詢優化的 7 個技巧

java小蟲 發佈 2024-04-28T05:04:15.353837+00:00

在優化性能時,開發人員和架構師通常會忽略調整他們的 SQL 查詢。了解資料庫的工作原理和編寫更好的 SQL 查詢在提高性能方面發揮著巨大作用 。 高效的 SQL 查詢意味著高質量、可擴展的應用程式。技巧 1:為列選擇合適的數據類型SQL 中的每個表列都有一個關聯的數據類型。

在優化性能時,開發人員和架構師通常會忽略調整他們的 SQL 查詢。了解資料庫的工作原理和編寫更好的 SQL 查詢在提高性能方面發揮著巨大作用 高效的 SQL 查詢意味著高質量、可擴展的應用程式。

技巧 1:為列選擇合適的數據類型

SQL 中的每個表列都有一個關聯的數據類型。您可以選擇整數、日期、varchars、布爾值、文本等。開發時,選擇正確的數據類型很重要。數字應該是數字類型,日期應該是日期等等,這對於索引是極其重要的。

讓我們看看下面的例子。

SELECT employeeID, employeeName
FROM employee
WHERE employeeID = 13412;
複製代碼

上面的[查詢]獲取 ID 為員工的員工 ID 和姓名13412。如果 employeeID 的數據類型是字符串怎麼辦? 使用索引時您可能會遇到麻煩,因為當它應該是一個簡單的掃描時,它會花費很長時間。

技巧 2:表變量和連接

當您有複雜的查詢時,例如獲取客戶的訂單以及他們的姓名和訂單日期,您需要的不僅僅是一個簡單的選擇語句。在本例中,我們從客戶和訂單表中獲取數據。這就是[加入]進來的地方。

讓我們看一下連接的例子:

SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers ON Orders.CustomerID=Customers.CustomerID;
複製代碼

SQL 提供inner、full、left outer和right outer類型的聯接。

表變量是臨時存儲數據的局部變量,具有局部變量的所有屬性。不要在連接中使用表變量,因為 SQL 將它們視為單行。儘管它們速度很快,但表變量在連接中的表現並不好。

技巧 3:使用條件WHERE從句

條件WHERE子句用於子集化。假設您遇到這樣的情況:

-if SEQ_VAR in (1, 2, 3) & diff(DATE_VAR2, DATE_VAR1)≥ 0
— elif SEQ_VAR in (4, 5, 6) & diff(DATE_VAR2, DATE_VAR1) ≥1
— else diff(DATE_VAR2, DATE_VAR1) ≥2
複製代碼

使用條件WHERE子句,它看起來像這樣:

SELECT 
  DAT.ID_VAR,
  DAT.SEQ_VAR,
  DAT.NUM_VAR,
  DATE_VAR1,
  DATE_VAR2,
  TRUNC(DATE_VAR2) - TRUNC(DATE_VAR1) AS LAG_IN_DATES

FROM 
  CURRENT_TABLE      DAT 
WHERE
  (TRUNC(DATE_VAR2) - TRUNC(DATE_VAR1)) >= CASE WHEN SEQ_VAR IN (1,2,3) THEN 0 WHEN SEQ_VAR IN (4,5,6) THEN 1 ELSE 2 END 
ORDER BY ID_VAR, SEQ_VAR
複製代碼

技巧 4:使用SET NOCOUNT ON

執行INSERT、SELECT、DELETE和UPDATE操作時,請使用SET NOCOUNT ON。SQL 總是為此類操作返回受影響的行數,因此當您有包含大量連接的複雜查詢時,它會影響性能。

使用SET NOCOUNT ON,SQL 將不會計算受影響的行並提高性能。

在以下示例中,我們阻止顯示有關受影響的行數的消息。

USE AdventureWorks2012;  
GO  
SET NOCOUNT OFF;  
GO  
-- Display the count message.  
SELECT TOP(5)LastName  
FROM Person.Person  
WHERE LastName LIKE 'A%';  
GO  
-- SET NOCOUNT to ON to no longer display the count message.  
SET NOCOUNT ON;  
GO  
SELECT TOP(5) LastName  
FROM Person.Person  
WHERE LastName LIKE 'A%';  
GO  
-- Reset SET NOCOUNT to OFF  
SET NOCOUNT OFF;  
GO  
複製代碼

提示 5:避免ORDER BY、GROUP BY和DISTINCT

僅在必要時使用ORDER BY、GROUP BY和。DISTINCTSQL 創建工作表並將數據放在那裡。然後它根據查詢組織工作表中的數據,然後返回結果。

技巧 6:完全限定資料庫對象名稱

使用完全限定的資料庫對象名稱的目的是消除歧義。完全限定的對象名稱如下所示:

DATABASE.SCHEMA.OBJECTNAME.
複製代碼

當您有權訪問多個資料庫、模式和表時,指定要訪問的內容就變得很重要。除非您正在使用具有多個用戶和模式的大型資料庫,否則您不需要這樣做,但這是一個很好的做法。

所以不要使用像這樣的語句:

SELECT * FROM TableName
複製代碼

你應該使用:

SELECT * FROM dbo.TableName
複製代碼

技巧 7:了解如何完全保護您的代碼

資料庫存儲各種信息,使它們成為主要的攻擊目標。常見的攻擊包括[SQL 注入] ,用戶輸入 SQL 語句而不是用戶名並檢索或修改您的資料庫。SQL注入的例子包括:

textuserID = getRequestString("userID");
textSQL = "SELECT * FROM Users WHERE userID = " + textuserID;
複製代碼

假設你有這個,textuserID將從用戶那裡獲取輸入。這是它可能出錯的原因:

SELECT * FROM Users WHERE userID = 890 OR 1=1;
複製代碼

由於1=1始終為真,它將從 Users 表中獲取所有數據。

您可以使用參數化語句、輸入驗證、清理輸入等來保護您的資料庫免受 SQL 注入攻擊。如何保護您的資料庫取決於 DBMS。您需要了解您的 DBMS 及其安全問題,這樣您才能編寫安全的代碼。


連結:https://juejin.cn/post/7205785488031154237

關鍵字: