Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL] 6 mln rekordów, indeks i SELECT wykonujący się grubo ponad minutę., Co może być przyczyną?
adbacz
post 10.08.2017, 17:02:12
Post #1





Grupa: Zarejestrowani
Postów: 532
Pomógł: 24
Dołączył: 15.04.2011
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


W tabeli mam ponad 6 mln rekordów, założony indeks na kolumnę 'created_at_timestamp' i wykonuję zapytanie po rekordy:
  1. (SELECT id FROM link WHERE ( created_at_timestamp <= 1485024231 AND created_at_timestamp >= 1484160231 ) ORDER BY id LIMIT 0, 1) UNION (SELECT id FROM link WHERE ( created_at_timestamp <= 1485024231 AND created_at_timestamp >= 1484160231 ) ORDER BY id LIMIT 99, 1)

To zapytanie wykonuje się naprawdę baaardzo długo: https://prnt.sc/g6g3ac

Sprawdziłem profilerem w PMA i pokazuje, że najdłużej działa Sending Data: https://prnt.sc/g6ggo2

Co może być tego przyczyną? Miał ktoś podobny problem?
Go to the top of the page
+Quote Post
bostaf
post 11.08.2017, 10:03:25
Post #2





Grupa: Zarejestrowani
Postów: 374
Pomógł: 79
Dołączył: 6.04.2010
Skąd: Ostrów Wielkopolski

Ostrzeżenie: (0%)
-----


Z manuala:

Cytat
Sending data
The thread is reading and processing rows for a SELECT statement, and sending data to the client. Because operations occurring during this state tend to perform large amounts of disk access (reads), it is often the longest-running state over the lifetime of a given query.


Czyli mimo że z nazwy ten wątek wygląda na czyste przesyłanie danych, to z opisu wynika, że w grę wchodzi też czytanie i przetwarzanie całego setu. Na localu sam czas przesłania miałby marginalną wartość, co możnaby sprawdzić na przykład w MySQL Workbenchu czytając wartość "Fetch".

A daj jeszcze przed całym zapytaniem EXPLAIN i pokaż wynik. Może da się jakoś zoptymalizować całe zapytanie.
Go to the top of the page
+Quote Post
adbacz
post 11.08.2017, 16:41:20
Post #3





Grupa: Zarejestrowani
Postów: 532
Pomógł: 24
Dołączył: 15.04.2011
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


Dziękuję za zainteresowanie tematem. Screen z rezultatu zapytania EXPLAIN:

http://prntscr.com/g7a9vs

Ten post edytował adbacz 11.08.2017, 16:41:36
Go to the top of the page
+Quote Post
Pyton_000
post 16.08.2017, 06:57:23
Post #4





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Wszystko jest ok. Po prostu zanim mysql wymieli Ci wynik i zwróci mija trochę czasu. A widać że zwraca Ci ~350k rekordów więc zanim poskacze po dysku i to odczyta ...

Go to the top of the page
+Quote Post
adbacz
post 22.08.2017, 17:51:54
Post #5





Grupa: Zarejestrowani
Postów: 532
Pomógł: 24
Dołączył: 15.04.2011
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


Padły nam dyski SSD i robiliśmy migrację, myślałem, że to od tego ale jednak nie. Nadal tak długo to działa. Muszę po prostu inaczej podejść do problemu. Dziękuję za odpowiedzi.
Go to the top of the page
+Quote Post
Crozin
post 22.08.2017, 18:11:20
Post #6





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Mógłbyś zastanowić się nad utworzeniem indeksu, który będzie zawierać zarówno kolumnę created_at jak i id. Wtedy baza danych w ogóle nie będzie musiała dotykać dysku bo wszystkie dane odczyta bezpośrednio z indeksu: https://dev.mysql.com/doc/refman/5.7/en/glo..._covering_index
Go to the top of the page
+Quote Post
adbacz
post 23.08.2017, 17:52:57
Post #7





Grupa: Zarejestrowani
Postów: 532
Pomógł: 24
Dołączył: 15.04.2011
Skąd: Kalisz

Ostrzeżenie: (0%)
-----


Mam utworzone indeksy na te dwie kolumny: https://ibb.co/gab9rk

PS. Da się jakoś wymusić na bazie, by trzymała pewne dane w RAMie? Na przykład indeksy? Na serwerze mamy 64GB RAMu, może to by przyspieszyło operacje.

Ten post edytował adbacz 23.08.2017, 17:54:04
Go to the top of the page
+Quote Post
Crozin
post 24.08.2017, 11:35:26
Post #8





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


1. Tabele typu MEMORY są trzymane właśnie w pamięci.
2. Indeksy są trzymane w pamięci.
3. Masz utworzone dwa indeksy na dwie kolumny, a potrzbowałbyś jednego na dwie kolumny by skorzystać z tego mechanizmu.
Go to the top of the page
+Quote Post
sazian
post 24.08.2017, 20:51:26
Post #9





Grupa: Zarejestrowani
Postów: 1 043
Pomógł: 141
Dołączył: 19.09.2006
Skąd: B-tów

Ostrzeżenie: (0%)
-----


Patrząc na ilość tych indeksów nasuwa się mi się jedno pytanie: czy ta tabela ma aż tyle kolumn czy może utworzyłeś indeksy na wszystkich kolumnach ?
Go to the top of the page
+Quote Post
trueblue
post 24.08.2017, 21:23:44
Post #10





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Sprawdź co będzie po zmianie na UNION ALL.


--------------------
Go to the top of the page
+Quote Post
Pilsener
post 25.08.2017, 07:31:14
Post #11





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


1. Kolejność w WHERE ustaw tak, aby na początku był warunek wykluczający najwięcej rekordów.
2. Dość kosztowne jest sortowanie dużych tabel.
3. Sprawdzałbym po kolei od najprostszego zapytania typu "select id from link limit 0, 1", by znaleźć przyczynę
4. Nie wszystko da się zoptymalizować, pewnych rzeczy się nie przeskoczy
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 18.04.2024 - 08:50