أتقِن قاعدة البادئة اليسرى، والفهارس المُغطِّية، والمزالق التي تجعل الفهرس غير مرئيّ للمُخطِّط.
افتح هذا الدرس في Kodokonيرتّب الفهرس المركّب الصفوف عبر عدة أعمدة، بالترتيب المُصرَّح به. والقاعدة الحاسمة هي البادئة اليسرى: يمكن لفهرس على (a, b) أن يخدم مرشِّحًا على a، أو على a و b، لكن ليس على b وحده أبدًا. وبالتالي فإن ترتيب الأعمدة خيار تصميمي، لا تفصيلًا. أنشئ أولًا مجموعة البيانات أدناه.
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. قارِن بين الخطتين.
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) موجود ضمنيًّا في كل فهرس، لذا فهو مُغطًّى مجانًا أيضًا.
-- 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=?)(department_id, salary)، أيّ استعلام لا يمكنه استخدامه؟email؟