大家好,我是全棧小5,歡迎來到《小5講堂》。
這是《Sql Server》系列文章,每篇文章將以博主理解的角度展開講解。
溫馨提示:博主能力有限,理解水平有限,若有不對之處望指正!
目錄
- 前言
- SQL 創建索引的基本語法和示例
- 基本語法
- 常見索引創建示例
- 1. 創建簡單非聚集索引
- 2. 創建唯一索引
- 3. 創建聚集索引
- 4. 創建復合索引(多列索引)
- 5. 包含額外列的索引(覆蓋索引)
- 6. 使用篩選條件創建篩選索引
- 7. 在線創建索引(減少鎖影響)
- 8. 指定填充因子
- 高級選項
- 并行創建索引
- 使用 tempdb 排序
- 在特定文件組上創建索引
- 注意事項
- 實用查詢小技巧
- 技巧說明
- 基本語法
- 實際示例
- 適用場景
- 注意事項
- 替代方案
- 文章推薦
前言
由于博主用的云服務器配置比較低,2M帶寬,所以整體訪問速度會比較慢,單達到一定內存和并發上限后會出現查詢超時的情況。
此時就在硬件不變動情況下,就需要從軟件層面優化,sql表索引就是常見的查詢優化方向之一,
如果你用的是SSMS可視化工具操作sql server數據庫,那么通過可視化方式去創建索引可能會失敗,可以換成通過sql方式創建!
SQL 創建索引的基本語法和示例
以下是 SQL Server 中創建索引的完整語法和常見示例:
基本語法
CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name
ON table_name (column1 [ASC|DESC], column2 [ASC|DESC], ...)
[INCLUDE (column_name [, ...])]
[WITH (index_option [, ...])]
[ON filegroup_name | partition_scheme_name (column_name)]
常見索引創建示例
1. 創建簡單非聚集索引
CREATE INDEX IX_Customer_LastName ON Customers(LastName);
2. 創建唯一索引
CREATE UNIQUE INDEX IX_Employee_Email ON Employees(Email);
3. 創建聚集索引
CREATE CLUSTERED INDEX IX_Orders_OrderDate ON Orders(OrderDate);
4. 創建復合索引(多列索引)
CREATE INDEX IX_Products_CategoryPrice ON Products(CategoryID, UnitPrice DESC);
5. 包含額外列的索引(覆蓋索引)
CREATE INDEX IX_Orders_CustomerDate
ON Orders(CustomerID, OrderDate)
INCLUDE (TotalAmount, Status);
6. 使用篩選條件創建篩選索引
CREATE INDEX IX_ActiveProducts ON Products(ProductName)
WHERE Discontinued = 0;
7. 在線創建索引(減少鎖影響)
CREATE INDEX IX_Customer_Region ON Customers(Region) WITH (ONLINE = ON);
8. 指定填充因子
CREATE INDEX IX_OrderDetails_ProductID
ON OrderDetails(ProductID)
WITH (FILLFACTOR = 70);
高級選項
并行創建索引
CREATE INDEX IX_LargeTable_Column ON LargeTable(Column1) WITH (MAXDOP = 4);
使用 tempdb 排序
CREATE INDEX IX_LargeTable_Column ON LargeTable(Column1) WITH (SORT_IN_TEMPDB = ON);
在特定文件組上創建索引
CREATE INDEX IX_LargeTable_Column ON LargeTable(Column1) ON INDEX_FG;
注意事項
- 表名和列名區分大小寫取決于數據庫的排序規則設置
- 每個表只能有一個聚集索引
- 創建索引會占用系統資源,大型表上創建索引可能需要較長時間
- 索引會提高查詢性能但會降低插入、更新和刪除操作的性能
- 定期維護索引(重建或重組)以保持性能
實用查詢小技巧
使用 WITH (NOLOCK)
減少阻塞
技巧說明
在SQL Server中,當需要快速查詢數據而不需要絕對最新的數據或精確一致性時,可以使用WITH (NOLOCK)
提示(也稱為"臟讀")。這可以避免查詢被其他事務阻塞,提高查詢速度,特別是在高并發環境下。
基本語法
SELECT 列名1, 列名2, ...
FROM 表名 WITH (NOLOCK)
WHERE 條件;
實際示例
-- 普通查詢(可能被其他事務阻塞)
SELECT OrderID, CustomerID, OrderDate
FROM Orders
WHERE OrderDate > '2023-01-01';-- 使用NOLOCK的查詢(不會被阻塞,但可能讀到未提交的數據)
SELECT OrderID, CustomerID, OrderDate
FROM Orders WITH (NOLOCK)
WHERE OrderDate > '2023-01-01';
適用場景
- 報表查詢,對實時性要求不高
- 大數據量分析查詢
- 開發調試環境
- 系統監控查詢
注意事項
- 可能讀取到未提交的數據(臟讀) - 如果其他事務回滾,你讀到的數據可能不存在
- 不保證數據一致性 - 可能讀到部分更新的數據
- 不適合財務等關鍵業務 - 對于需要精確數據的場景不應使用
- 不是表鎖的替代品 - 不能解決所有并發問題
替代方案
如果擔心臟讀但需要減少阻塞,可以考慮:
-- 使用READ UNCOMMITTED隔離級別(會話級設置)
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT OrderID, CustomerID, OrderDate
FROM Orders
WHERE OrderDate > '2023-01-01';
SET TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 恢復默認
文章推薦
【數據庫】使用Sql Server創建索引優化查詢速度,一般2萬多數據后,通過非索引時間字段排序查詢出現超時情況
【數據庫】SQL Server 查詢條件小技巧:ISNULL 函數的使用,有請DeepSeek來輔助講解下
【Sql Server】在SQL Server中生成雪花ID(Snowflake ID)
【Sql Server】使用row_number over方式進行表分頁,數據量達到五千多條記錄后,查詢變慢需要20多秒的解決方案
【Sql Server】隨機查詢一條表記錄,并重重溫回顧下自定義函數的封裝和使用
【Sql Server】鎖表如何解鎖,模擬會話事務方式鎖定一個表然后進行解鎖
【Sql Server】通過Sql語句批量處理數據,使用變量且遍歷數據進行邏輯處理
【新星計劃回顧】第六篇學習計劃-通過自定義函數和存儲過程模擬MD5數據
【新星計劃回顧】第四篇學習計劃-自定義函數、存儲過程、隨機值知識點
【Sql Server】Update中的From語句,以及常見更新操作方式
【Sql server】假設有三個字段a,b,c 以a和b分組,如何查詢a和b唯一,但是c不同的記錄
【Sql Server】新手一分鐘看懂在已有表基礎上修改字段默認值和數據類型
總結:溫故而知新,不同階段重溫知識點,會有不一樣的認識和理解,博主將鞏固一遍知識點,并以實踐方式和大家分享,若能有所幫助和收獲,這將是博主最大的創作動力和榮幸。也期待認識更多優秀新老博主。