Użycie kolumny w SELECT a wybór indeksu

0

Witam.

Zauważyłem, że podczas wykonywania zapytania dla jednej tabeli idzie full scan mimo, że są dodane indeksy które wydawałby się powinny zostać użyte.
Ku mojemu zaskoczeniu na wybór indeksu ma wpływ to jakie pola użyte są SELECT

Na przykład to zapytanie:

EXPLAIN EXTENDED 
SELECT  
  ngl.id
FROM kontrahenci kh 
JOIN naglowki ngl ON ngl.kh_id = kh.id
WHERE ngl.`data` >= "2021-10-25"

zwrócony plan:

id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra

---------------- | -------------------
1|SIMPLE|ngl|index|q1|q1|9|NULL|24784|20.22|Using where; Using index
1|SIMPLE|kh|eq_ref|PRIMARY,id_UNIQUE|PRIMARY|4|ngl.kh_id|1|100.00|Using index

Zgodnie z oczekiwaniami został użyty indeks q1.
Jednak w przypadku gdy dodam kolejną kolumnę w select indeks już nie jest używany.

EXPLAIN EXTENDED 
SELECT  
  ngl.id,
  ngl.strefa
FROM kontrahenci kh 
JOIN naglowki ngl ON ngl.kh_id = kh.id
WHERE ngl.`data` >= "2021-10-25"

id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra

---------------- | -------------------
1 | SIMPLE | ngl | ALL | q1 | NULL | NULL | NULL | 24784 | 20.22 | Using where
1 | SIMPLE | kh | eq_ref | PRIMARY,id_UNIQUE | PRIMARY | 4 | ngl.kh_id | 1 | 100.00 | Using index

Czy to znaczy, że w indeksie muszę zawszeć wszystkie kolumny które będą użyte w select.

Wydawało mi się, że w indeksie musza być użyte kolumny których używam przy złączeniach, warunkach wyszukiwania, sortowania, grupowania, agregowania a tych wybieranych do zwrócenia nie musi być...

Z góry dziękuję za pomoc

2

Najwyraźniej MySQL stwierdził, że dla Twojego rozmiaru tabeli full table scan będzie zwyczajnie szybszy niż odpytywanie na przemian indeksu oraz danych tabeli:

https://dev.mysql.com/doc/refman/8.0/en/table-scan-avoidance.html:
[... MySQL uses full table scan when ...] The table is so small that it is faster to perform a table scan than to bother with a key lookup. This is common for tables with fewer than 10 rows and a short row length.

(w przypadku odpytywania o części większych tabel - np. tabela ma 10 kolumn, a Ty odpytujesz tylko o kilka z nich - warto, aby indeks pokrywał wszystkie pola wykorzystane w select, where itd. - nazywa się to covering index.)

1

A jaka duża jest tabela? Jak nie jest duża, odczytanie tabeli może być szybsze niż odczytanie indeksu i wybieranie wierszy. Tyle tylko, że w pierwszym przypadku tez by to miało sens - czyli tez powinien czytać całą tabelę.

1

Jak chcesz tam uzyc indeksu to zaloz go na date. Prawdopodobnie bedzie to lepsze niz PK w tym wypadku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1