數據庫是一組數據,其排列方式易于檢索、管理和更新。數據存儲在行、列和表中。它被編入索引以更快地檢索所需信息。首先我們簡要討論基礎知識,然后我們將繼續討論這個常見問題——如何優化數據庫響應時間?
數據庫類型
主要有四種結構的數據庫管理系統:
- 分層數據庫
- 網絡數據庫
- 關系型數據庫
- 面向對象的數據庫
最近,NoSQL 和面向對象的數據庫已經發展到用于存儲數據。NoSQL 數據庫不遵循行/列/表方法。NoSQL 數據庫是基于文檔的,包括鍵值對的集合,圖形數據庫沒有 RDBMS 中的傳統模式。NoSQL 數據庫非常適合處理大量分布式數據。只有有限的外部專家可以協助設置和部署大規模 NoSQL 部署。
關系數據庫是最常用的數據庫系統。SQL Server、Oracle 數據庫、Sybase 和 MySql 是關系數據庫的一些示例。RDBMS 允許多個用戶同時訪問數據,而不會影響安全因素。RDBMS 中的表的工作方式類似于電子表格。一組表被稱為模式。許多模式組合在一起構成了一個數據庫。單個服務器可以包含多個數據庫。
現在讓我們討論如何優化數據庫響應時間
在設計數據庫之前和編寫 SQL 腳本以優化數據庫響應之前,必須考慮下面提到的技巧。
1. 數據庫統計信息:?SQL 優化器必須非常了解每個目錄中不同表中包含的統計信息。有關索引及其分布的詳細信息稱為統計信息。使用這些細節,優化器決定滿足查詢的最佳路徑。過時或丟失的統計詳細信息將導致優化器采用非最佳路徑,從而導致響應時間增加。考慮以下示例查詢:
select *
from Customer
where city = “Pune”
and phone =213-345-346;
這里的 Customer 是表名。
在上面的查詢中,Where 子句有兩個字段。定義了兩個索引,每個索引包含一個字段。優化器每個表只能使用一個索引。在這種情況下,如果優化器使用 phone 字段作為返回最少行數的索引,查詢將運行得更快。所以,如果數據庫沒有正確更新,如果沒有選擇正確的字段作為索引,響應時間將會大大增加。
2. 構建優化索引:索引對于構建任何查詢都非常重要。但是,許多索引會降低(插入、更新或刪除)查詢的速度。有必要保持表上索引的適當平衡。表中包含的字段及其順序也起著至關重要的作用。
(a) 復合索引:當一個索引包含多個字段時,稱為復合索引。當執行在 where 子句中包含多個字段的查詢時,會構建復合索引。在這種情況下,與單獨的第一個字段相比,所有字段組合在一起將顯著生成最少的行數。
(b) 聚集索引: 表中數據排列的物理順序稱為聚集索引。這意味著實際數據是根據索引字段排序的。示例:其中數據按某人的姓氏排列的電話簿。每個表只能有一個聚集索引。聚集索引通常用于經常在列中搜索一系列值的情況。
3. 避免在運算符的 RHS 上使用函數:?函數和方法經常用于SQL 查詢。考慮下面的例子:
選擇 *
from Customer
where YEAR(Sample CreatedOn) == 2009
AND Month(SampleCreatedON) = 6;
在上面的查詢中,SampleCreatedOn 有一個索引。但是, where 子句以這樣的方式更改,無法使用該索引。以下面的方式修改查詢會極大地增加響應時間。
select * from Customer where SampleCreatedOn between '6/1/2009' and '6/30/2009';
4. 指定索引的預期增長:?最小化索引負面影響的一種方法是在創建索引時為預期增長指定適當的值。
索引列的數據通常存儲在磁盤上。如果表中包含新行或修改索引列中的現有值,數據庫必須重新組織數據存儲以累積新行。這種重組會影響查詢的響應時間。在這種情況下,如果定期合并新行,則可以預先指定索引的預期增長。在 MS SQL Server 中,用于表示預期增長的術語是 FILL FACTOR,而對于 Oracle 和 DB2,它是 PCTFREE,意思是免費百分比。
5. 在 SELECT 中包含優化器提示:?在選擇查詢中提及索引名稱始終是一個好習慣。考慮下面的例子。
select * from Customer
with (Index(IdxPhone))
where city = “Pune” AND phone = '213-345-346';
FROM 后面的附加 WITH 子句指示索引名稱將有助于增加查詢的響應時間。上面的示例特定于 MS SQL SERVER。
6、EXPLAIN的使用:?優化器創建的SELECT語句的執行計劃,多數情況下是由數據庫返回的。這種執行對微調 SQL 查詢有很大幫助。
執行計劃的 SQL 語法是 Set SHOWPLAN_ALL ON>Query<。WINSQL Professional等工具也可用于運行 EXPLAIN 命令。
7. 避免外鍵約束:?使用外鍵約束可確保數據完整性,但以性能為代價。如果優化響應時間是主要目標,則可以避免外鍵約束。例如: RDBMS 中的 System 表包含有關用戶數據庫的元數據信息。此處包含的表包含關系但沒有外鍵。此處的客戶端強制執行這些規則以優化數據庫響應時間。
8、多塊硬盤的使用:?隨著數據庫容量的增加,硬盤上的I/O操作明顯變慢。可以將數據庫拆分到多個物理硬盤驅動器以加快 I/O。也可以將一個表的內容拆分到多個磁盤中。隨著更多磁頭并行檢索數據,使用多個磁盤可提高 I/O 操作的速度
9. 選擇最少數據:?檢索到的最少數據,查詢運行得越快。過濾盡量在服務端進行,而不是在客戶端進行過濾。這將導致處理的數據最少,并提供更快的結果。消除任何計算列或不必要的列。考慮下面的例子:
選擇名字、姓氏、城市,其中城市 =“浦那”;
在上面的示例中,可以避免城市列,因為它始終是 Pune。盡管它不會產生很大的影響,但它可以改善大型數據集的響應時間。
10. 加載數據前刪除索引。
可以在加載大量數據之前刪除表上的索引。這允許插入語句更快地工作。插入完成后,可以再次重新創建索引。
對于需要插入數千行的在線系統,可以使用臨時表來加載數據。這個臨時表不應該有任何索引。將數據從一個表傳輸到另一個表總是比從外部源加載快得多。刪除主表上的索引,將數據從臨時表傳輸到最終表,最后再次創建索引。
優化響應時間的更多技巧
- 避免使用 Group By、Order By 和 Distinct: 必須盡可能避免使用 Group By、Order By 和 Distinct。使用上述子句時,SQL Server 會創建一個臨時表并將數據加載到該表中。根據查詢的請求在此臨時表中處理數據并檢索最終結果。因此,在絕對必要時,始終建議在查詢中使用 Group By、Order By 和 Distinct。
- Use Set NOCOUNT ON: Set NOCOUNT ON 必須用于 DML 操作(插入、更新、刪除和選擇)。SQL server 默認計算并返回受影響的行數。小型查詢不會受到太大影響,但是對于具有大量連接的大型復雜查詢,這會導致很大的性能問題。設置 NOCOUNT ON 肯定會增加響應時間,因為它不會計算受影響的行數。
- 包括所有者/架構名稱: 表的對象名稱,存儲過程必須與所有者/架構名稱一起作為前綴。如果省略所有者/架構名稱,則服務器將在所有架構中搜索該對象,直到找到該對象。指定所有者/模式指示服務器僅在該特定模式中搜索表。
- 可空列: 在與可空列進行比較時,避免使用 NOT IN 并使用 NOT EXISTS。當在查詢中使用 NOT IN 時,SQL Server 將檢查每個結果(即使沒有包含空值的行)以確定它是否為空。NOT EXISTS 不執行與空值的比較檢查。
- 調整內部變量: 微調一些默認設置有助于加快響應時間和提高性能。
更改索引緩沖區大小 (key_buffer)
在管理表索引(讀取和寫入操作)時,可以借助此變量控制緩沖區大小。該變量的值可以增加到系統總內存的 25% 左右。要縮短響應時間,請嘗試為此變量使用不同的值。
更改表緩沖區大小 (read_buffer_size)
在查詢需要按順序檢查表的情況下,MySQL 為該查詢提供內存緩沖區。緩沖區大小由 read_buffer_size 變量控制。如果順序掃描需要更多時間,則可以通過增加此值的大小以及內存緩沖區的大小來提高性能。
設置最大打開表數(table_cache)
在任何特定時間可以打開的最大表數由 table_cache_variable 管理。此變量類似于 max_connections 變量。增加此變量的值允許大量表保持打開狀態。如果服務器收到對各種數據庫和表的查詢,則可以更改 table_cache 值。
為長查詢指定時間限制 (long_query_time)
使用 long_query_time 變量允許跟蹤低效或行為不當的查詢。這個變量對提高響應時間和優化性能有很大幫助。