Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да оптимизираме заявките в база данни - Основите

Трябва да направите преглед за всяко условие и за всяко присъединяване...при условие. Двете работят еднакво.

Да предположим, че пишем

select name
from customer
where customerid=37;

По някакъв начин СУБД трябва да намери записа или записи с customerid=37. Ако няма индекс, единственият начин да направите това е да прочетете всеки запис в таблицата, сравнявайки customerid с 37. Дори когато намери такъв, няма начин да знае, че има само един, така че трябва да продължи да търси други.

Ако създадете индекс на customerid, СУБД има начини да търси индекса много бързо. Това не е последователно търсене, а, в зависимост от базата данни, двоично търсене или друг ефикасен метод. Как точно няма значение, приемете, че е много по-бързо от последователното. След това индексът го отвежда директно към съответния запис или записи. Освен това, ако посочите, че индексът е "уникален", тогава базата данни знае, че може да има само един, така че да не губи време да търси секунда. (И СУБД ще ви попречи да добавите втори.)

Сега помислете за тази заявка:

select name
from customer
where city='Albany' and state='NY';

Сега имаме две условия. Ако имате индекс само за едно от тези полета, СУБД ще използва този индекс, за да намери подмножество от записи, след което последователно ще ги търси. Например, ако имате индекс на състояние, СУБД бързо ще намери първия запис за Ню Йорк, след което последователно ще търси city='Albany' и ще спре да търси, когато достигне последния запис за NY.

Ако имате индекс, който включва и двете полета, т.е. „създайте индекс на клиент (щат, град)“, тогава СУБД може незабавно да увеличи мащаба до правилните записи.

Ако имате два отделни индекса, по един за всяко поле, СУБД ще има различни правила, които прилага, за да реши кой индекс да използва. Отново, как точно се прави това зависи от конкретната СУБД, която използвате, но основно се опитва да поддържа статистика за общия брой записи, броя на различните стойности и разпределението на стойностите. След това ще търси последователно тези записи за тези, които отговарят на другото условие. В този случай СУБД вероятно ще забележи, че има много повече градове, отколкото има щати, така че с помощта на индекса на града може бързо да приближи до записите 'Albany'. След това ще ги търси последователно, като проверява състоянието на всеки спрямо 'NY'. Ако имате записи за Олбани, Калифорния, те ще бъдат пропуснати.

Всяко присъединяване изисква някакво търсене.

Кажете, че пишем

select customer.name
from transaction
join customer on transaction.customerid=customer.customerid
where transaction.transactiondate='2010-07-04' and customer.type='Q';

Сега СУБД трябва да реши коя таблица да прочете първа, да избере подходящите записи оттам и след това да намери съвпадащите записи в другата таблица.

Ако сте имали индекс за транзакция.transactiondate и customer.customerid, най-добрият план вероятно би бил да намерите всички транзакции с тази дата и след това за всяка от тях да намерите клиента със съответстващия идентификатор на клиента и след това да проверите дали клиентът има правилния тип.

Ако нямате индекс на customer.customerid, тогава СУБД може бързо да намери транзакцията, но след това за всяка транзакция ще трябва да търси последователно в таблицата на клиентите, търсейки съответстващ customerid. (Това вероятно ще бъде много бавно.)

Да предположим вместо това, че единствените индекси, които имате, са на transaction.customerid и customer.type. Тогава СУБД вероятно ще използва напълно различен план. Вероятно ще сканира таблицата с клиенти за всички клиенти с правилния тип, след което за всеки от тях ще намери всички транзакции за този клиент и последователно ще ги търси за правилната дата.

Най-важният ключ към оптимизацията е да разберете кои индекси наистина ще помогнат и да създадете тези индекси. Допълнителните, неизползвани индекси са тежест за базата данни, защото е необходима работа за поддържането им, а ако никога не са използвани, това е пропиляно усилие.

Можете да кажете какви индекси ще използва СУБД за дадена заявка с командата EXPLAIN. Използвам това през цялото време, за да определя дали заявките ми се оптимизират добре или трябва да създавам допълнителни индекси. (Прочетете документацията за тази команда за обяснение на нейния изход.)

Предупреждение:Не забравяйте, че казах, че СУБД поддържа статистика за броя на записите и броя на различните стойности и така нататък във всяка таблица. EXPLAIN може да ви даде напълно различен план днес, отколкото вчера, ако данните са се променили. Например, ако имате заявка, която съединява две таблици и едната от тези таблици е много малка, докато другата е голяма, тя ще бъде отклонена към четене първо на малката таблица и след това намиране на съвпадащи записи в голямата таблица. Добавянето на записи към таблица може да промени кой е по-голям и по този начин да накара СУБД да промени своя план. По този начин трябва да се опитате да направите EXPLAINS срещу база данни с реалистични данни. Изпълнението срещу тестова база данни с 5 записа във всяка таблица е с много по-малка стойност от работата срещу жива база данни.

Е, може да се каже още много, но не искам да пиша книга тук.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL 8 Общи изрази за таблица CTE

  2. Codeigniter И ИЛИ И

  3. MySQL Connector/C++ OS X 10.9 Mavericks и XCODE 5.0.2

  4. Използване на псевдоним за локалния сървър в MySQL

  5. MySQL Left Joins:Изберете всичко от една таблица, но само съвпадащата стойност във втората таблица с критерии