Kodokon kodokon.com

الفهارس المتقدمة: المركّب، والمُغطِّي، والفهرس المُتجاهَل

أتقِن قاعدة البادئة اليسرى، والفهارس المُغطِّية، والمزالق التي تجعل الفهرس غير مرئيّ للمُخطِّط.

11 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

يرتّب الفهرس المركّب الصفوف عبر عدة أعمدة، بالترتيب المُصرَّح به. والقاعدة الحاسمة هي البادئة اليسرى: يمكن لفهرس على (a, b) أن يخدم مرشِّحًا على a، أو على a و b، لكن ليس على b وحده أبدًا. وبالتالي فإن ترتيب الأعمدة خيار تصميمي، لا تفصيلًا. أنشئ أولًا مجموعة البيانات أدناه.

SQL
CREATE TABLE employees (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  department_id INTEGER,
  salary INTEGER NOT NULL
);

INSERT INTO employees
  (id, name, department_id, salary)
VALUES
  (1, 'Ada',    1, 65000),
  (2, 'Grace',  1, 72000),
  (3, 'Alan',   2, 58000),
  (4, 'Edsger', 1, 90000);
جدول اختبار للفهارس المركّبة.

لننشئ فهرسًا على (department_id, salary). إن مرشِّحًا يبدأ بـ department_id يُطلِق SEARCH. لكن مرشِّحًا على salary وحده يكسر البادئة اليسرى: فلا يستطيع المُخطِّط القفز مباشرةً إلى الصفوف الصحيحة ويرتدّ إلى SCAN. قارِن بين الخطتين.

SQL
CREATE INDEX idx_dept_salary
  ON employees (department_id, salary);

-- Leftmost prefix present: index used
EXPLAIN QUERY PLAN
SELECT id FROM employees
WHERE department_id = 1
  AND salary > 60000;
-- SEARCH ... USING INDEX idx_dept_salary

-- Leading column missing: index ignored
EXPLAIN QUERY PLAN
SELECT id FROM employees
WHERE salary > 60000;
-- SCAN employees
الفهرس نفسه يخدم حالة دون الأخرى.

يحتوي الفهرس المُغطِّي على كل عمود يقرؤه الاستعلام. عندئذٍ يجيب المُخطِّط مباشرةً من الفهرس، دون فتح الجدول: وهذا هو معنى USING COVERING INDEX. هنا، يغطّي الفهرس (department_id, salary) استعلامًا يقرأ هذين العمودين فقط. وتذكّر أن id (أي rowid) موجود ضمنيًّا في كل فهرس، لذا فهو مُغطًّى مجانًا أيضًا.

SQL
-- Every column read is in the index
EXPLAIN QUERY PLAN
SELECT department_id, salary
FROM employees
WHERE department_id = 1;
-- SEARCH employees USING COVERING INDEX
-- idx_dept_salary (department_id=?)
يجيب الفهرس وحده؛ ولا يُفتَح الجدول.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. بفهرس مركّب على (department_id, salary)، أيّ استعلام لا يمكنه استخدامه؟
    • WHERE department_id = 1
    • WHERE department_id = 1 AND salary > 60000
    • WHERE salary > 60000
    • WHERE department_id = 1 AND name = 'Ada'
  2. ما هو الفهرس المُغطِّي؟
    • فهرس يحتوي على كل عمود مقروء، فيتجنّب فتح الجدول
    • فهرس يغطّي عدة جداول في آنٍ واحد
    • فهرس يُعاد إنشاؤه تلقائيًّا بعد كل INSERT
    • مرادف لفهرس فريد على المفتاح الأساسي
  3. أيّ من هذه الشروط يمنع استخدام فهرس بسيط على email؟
    • WHERE email = 'a@b.co'
    • WHERE email > 'm'
    • WHERE lower(email) = 'a@b.co'
    • WHERE email IN ('a@b.co', 'c@d.co')