簡體   English   中英

當我們計算訪問頁數時,聚集索引與非聚集索引有什么區別?

[英]What is the difference clustered vs non-clustered index when we calculate number of accesses pages?

Employee (Ssn, FirstName, LastName, Gender, Age, Salary, DepartmentID) 假設: • 沒有索引。 • 總共有8,000,000 行。 • 250,000 行在 2,500 到 3,000 的薪水范圍內。 • 每頁有100 行。 • 400 個索引行適合一個非聚集索引葉頁。 在給定假設的情況下,下列查詢的頁面訪問次數是多少? 分別考慮每種情況。 a) Select Ssn From Employee Where Salary>2500 and Salary<3000 and DepartmentID=1; b) 在 Employee (Salary) 上創建聚簇索引 ixEmpSal; Select Ssn From Employee Where Salary>2500 and Salary<3000 and Gender='M';

我有一個員工表,我想知道任何查詢的頁面訪問次數。我不明白以下問題的某些部分

1-) 我如何使用這部分“適合非聚集索引葉頁的 400 個索引行”。 如果我將問題的“非聚集索引”部分變成“聚集索引”會發生什么

2-) 在問題的一部分中數據庫是否分別搜索每個和部分?我的意思是例如 satabase 搜索 Salary>2500 然后開始搜索 Salary<3000 然后搜索 DepartmenId

ps:我不太了解理論解釋你能用例子解釋嗎

首先,讓我為查詢推薦最佳索引

a) Select Ssn From Employee Where Salary>2500 and Salary<3000 and DepartmentID=1;

INDEX(DepartmentID, Salary) -- in this order

(這么寫,2500和3000都不算了,真的要嗎?)

b) 在 Employee (Salary) 上創建聚簇索引 ixEmpSal; Select Ssn From Employee Where Salary>2500 and Salary<3000 and Gender='M';

在 MySQL 中,唯一聚集索引PRIMARY KEY 並且,PK必須是唯一的。 (這使您的問題 1 無效)因此,該索引可能不可行。 相反,經常使用代理人。

id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
INDEX(gender, salary)

(我稍后會提出另一種選擇。)

MySQL 對數據(按 PK 排序)和每個輔助(非集群) INDEX使用 B+樹。 二級索引行有一個 PK 的副本來查找該行的 rest。

如果沒有好的索引,MySQL 將掃描整個表(“表掃描”)。 因為它是 B+Tree,而不僅僅是 BTree,所以它將只讀取葉節點(在通過向下鑽取樹一次找到“第一”行之后)。 所以閱讀的頁數大約是 8,000,000/100 + 4-1。

log-base-100 (8M) = 4,因此 B+Tree 的數據深度約為 4 層。 對於每個二級索引,log-base-400 (8M) ~= 3 級。

  • 只有INDEX(Salary) :250,000 / 400 ~= 625 個索引塊加上 4 * 250,000 個數據塊來檢查部門或性別,以及獲取所需的任何其他列(SSN,如前所述)。 數據塊(在這種情況下)將被大量緩存,尤其是非葉節點。

Select b假設一家平等主義的公司,50% 的性別=M。 現在我們正在查看 250,000 * 50% / 400 ~= 313 個索引塊。 如果需要,還有一半的數據塊。

InnoDB 使用 16KB 塊。 因此乘以它得到磁盤上和/或 buffer_pool 中的字節數(假設它都可以被緩存)。 為非葉節點添加大約 1%。

但是......一旦它在索引中找到“行”,它就需要進入數據 B+Tree 以獲得所需的任何其他列。 這將涉及向下鑽取數據的 B+ 樹+在這里無關緊要)以獲取每一行。 現在我們正在查看每個獲取的數據行 4 頁——但大部分都被緩存了。

一種不同的技術

PRIMARY KEY(Salary, id),  -- cluster on Salary
INDEX(id)                 -- to keep AUTO_INCREMENT happy
-- and neither of my indexes

現在您的兩個查詢只需要查看數據 B+Tree。 Select b 是 250,000 / 100 ~= 2500 個塊並且使用 B_Tree 的+並且不使用任何二級索引。 它將掃描所有 250K 行以查看哪些與 Dept 或 Gender 匹配,然后 SSN 立即可用。

請注意,將id添加到Salary可提供 PK 所需的唯一性。 所以這更接近你問的問題。

節點很少滿InnoDB 的塊通常在 1/2 到 15/16 之間滿,平均約為 70%。 這是因為來自更新/刪除/插入的塊拆分等。 這可能會混淆您的“100”和“400”,但不會混淆我提出的結論。

(你的問題 2)MySQL沒有在單個INDEXes中使用兩個索引。(極少數例外。)我建議的復合(多列)索引甚至比嘗試使用兩個索引更好。

(如果 SSN 位於您的數據庫中,安全性就更為重要。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM