В тази статия ще разгледаме как един индекс може да подобри ефективността на заявката.
Въведение
Индексите в Oracle и други бази данни са обекти, които съхраняват препратки към данни в други таблици. Те се използват за подобряване на производителността на заявката, най-често операторът SELECT.
Те не са „сребърен куршум“ – те не винаги решават проблеми с производителността с изрази SELECT. Те обаче със сигурност могат да помогнат.
Нека разгледаме това на конкретен пример.
Пример
За този пример ще използваме една таблица, наречена Клиент, която съдържа колони като ID, Име, Фамилия, максимална кредитна стойност, стойност на датата на създаване и други колони, които няма да използваме.
SELECT customer_id,first_name,last_name, max_credit, created_date FROM customer;
Ето извадка от таблицата.
[table id=38 /]
Сега ще намерим следното:
- Кой от клиентите е добавен към таблицата на една и съща дата с първите клиенти
- Клиенти, филтрирани по фамилия във възходящ ред
- Показване на идентификатора на клиента, собственото име, фамилията, максималния кредит и датата на създаване
За да направите това, създайте следната заявка:
SELECT customer_id, first_name, last_name, max_credit, created_date FROM customer WHERE created_date = ( SELECT MIN(created_date) FROM customer ) ORDER BY last_name;
Резултатът изглежда така:
[table id=39 /]
Показва данните, които искаме.
Ефективност преди прилагане на индекс
Сега нека разгледаме плана за обяснение на тази заявка. Получих това, като изпълних EXPLAIN PLAN FOR за оператора SELECT и следната команда:
SELECT * FROM TABLE(dbms_xplan.display);
Можете да получите подобен изходен резултат, като използвате и функцията Explain Plan във вашата IDE.
Можем да видим, че той извършва пълен достъп до таблица в две точки, а именно в подзаявката и във външната заявка. Това е така, защото в таблицата няма индекси, които да се използват.
Цената му е 2934. Когато го стартирах, заявката извади 785 реда за 1,9 секунди. Може да изглежда бързо, но това е само пример, който можем да подобрим. Заявките в реални системи могат да отнемат много повече време.
Един от начините да подобрим производителността на тази заявка е да добавим индекс към колоната created_date. Тази колона се използва както в клаузата WHERE на външната заявка, така и във функцията MIN на вътрешната заявка.
Добавяне на индекс
Можем да добавим индекс към тази таблица, за да подобрим ефективността на заявката. Този индекс ще бъде съхранен в колоната created_date, така че кодът да изглежда така:
CREATE INDEX idx_cust_cdate ON customer (created_date);
Сега индексът се създава само в тази колона. Това би трябвало да ни даде подобрение в производителността на нашата заявка, но първо ще трябва да го проверим.
Създадохме индекс на b-дърво, което вероятно е всичко, от което се нуждаем в тази колона. Скоро ще го потвърдим в плана за обяснение. Написах ръководство за индексите на Oracle, включително как да разбера какъв тип индекс да се използва, както и много друга ценна информация.
Ефективност след индекс Добавено
Нека изпълним отново плана за обяснение на тази заявка.
Можем да видим, че в последната стъпка е използван индекс. Показва, че е извършено пълно сканиране с индекса idx_cust_cdate, който току-що създадохме.
Той също така показва обща цена от 1472 и извлича 785 записа за 0,9 секунди.
Времето на изпълнение се е подобрило само леко (от 1,9 на 0,9 секунди), но това е около 50% подобрение само чрез добавяне на индекса към този малък набор от данни.
Както споменахме по-рано, истинските заявки ще бъдат по-сложни от тази и ще отнеме повече време за изпълнение. Но това е пример как един индекс може да подобри плана на заявката и времето за изпълнение на заявката.