Post
#1
|
|
|
Grupa: Zarejestrowani Postów: 1 086 Pomógł: 8 Dołączył: 10.12.2003 Ostrzeżenie: (0%)
|
Zaprojektowałem bazę danych do przechowywania dokumentów sprzedażowych z ich pozycjami. W uproszczeniu do istotnych kolumn wygląda ona tak:
Kod ┌────────────┐ ┌────────────┐ │ invoices │ │ items │ ├────────────┤ ├────────────┤ │ id │ 1 n │ id │ │ date ├────────┤ invoice_id │ │ number │ │ position │ │ contractor │ │ name │ └────────────┘ │ quantity │ │ price │ └────────────┘ Jak widać, w tabeli "invoices" nie przechowuję sumy pozycji. Dla wygody stworzyłem więc widok: Kod CREATE VIEW invoices_summary AS SELECT invoices.*, SUM(items.quantity * items.price) AS total FROM invoices LEFT JOIN items ON (items.invoice_id = invoices.id) GROUP BY invoices.id Powyższe działało bardzo fajnie na MySQL aż do rozrośnięcia się danych. Obecnie wyciągnięcie choćby jednego wiersza z "invoices_summary" trwa ok. 2 sekund. Przyczyną kulejącej wydajności jest ograniczenie algorytmu MERGE w MySQL: https://dev.mysql.com/doc/refman/8.0/en/view-algorithms.html MySQL nie potrafi użyć MERGE gdy widok korzysta z funkcji grupujących. Stąd każde zapytanie do "invoices_summary" to generowanie tymczasowej tabeli na podstawie setek tysięcy. Gdyby MySQL "przeniosło" moje WHERE do wnętrza widoku, wystarczyłoby kilkadziesiąt wierszy. Szukam pomysłu jak wybrnąc z tej sytuacji i potrzebuję pomocy. Rozważałem:
Czy ktoś ma jakieś inne pomysły albo ogólnie sugestie? |
|
|
|
![]() |
Post
#2
|
|
|
Grupa: Zarejestrowani Postów: 6 809 Pomógł: 1828 Dołączył: 11.03.2014 Ostrzeżenie: (0%)
|
EXPLAIN to w MySQL jakiś żart (IMG:style_emoticons/default/sad.gif) 3 bezwartościowe informacje (wiersze) Powodzenia w takim razie przy dalszej rozbudowie aplikacji i zaniechania używania:) A byłem taki dumny ze swoich widoków i prostego kodu SQL w aplikacji (IMG:style_emoticons/default/tongue.gif) Serwer to dzielony hosting mydevil, MySQL 5.7.26, ale problem obserwuję też loklanie na MadiaDB 10.4.13. Ale przekombinowałeś. To zapytanie, nawet z wyliczaniem sumy według stawek powinno wykonywać się w mgnieniu oka. Tak się składa, że pracuję z tabelami po kilkaset milionów rekordów i poprawnie założone indeksy pozwalają wykonywać zapytania poniżej dziesiątek sekundy. Wydaje mi się, że i tak nadal będziesz kombinował, aby na zewnątrz mieć SELECT * FROM widok. |
|
|
|
Post
#3
|
|
|
Grupa: Zarejestrowani Postów: 1 086 Pomógł: 8 Dołączył: 10.12.2003 Ostrzeżenie: (0%)
|
Powodzenia w takim razie przy dalszej rozbudowie aplikacji i zaniechania używania:) Uważam, że EXPLAIN jest bardzo przydatny i nikt (pracujący z większymi tabelami/zapytaniami) temu raczej nie zaprzeczy. Zaskoczyła mnie tylko jego uboga implementacja w MySQL, bo uczyłem się odczytywać wynik EXPLAIN w Oracle. Ale przekombinowałeś. To zapytanie, nawet z wyliczaniem sumy według stawek powinno wykonywać się w mgnieniu oka. Tak się składa, że pracuję z tabelami po kilkaset milionów rekordów i poprawnie założone indeksy pozwalają wykonywać zapytania poniżej dziesiątek sekundy. Wydaje mi się, że i tak nadal będziesz kombinował, aby na zewnątrz mieć SELECT * FROM widok. Przyznaję, że nie chcę za każdym zapytaniem robić copy & paste np. całego:
jakbym w C czy PHP nie zrobił z tego funkcji, każdy mi uznał to za pomyłkę. Może za bardzo przenoszę zwyczaje programistyczne do SQL. Zrobię sobie jednak trigger z powyższym kodem, myslę, że będzie to optymalne rozwiązanie. Waham się jedynie między zapisywaniem wyniku do osobnej kolumny (oryginalnej tabeli) a zapisywaniem do osobnej tabeli (emulując widok zmaterializowany). |
|
|
|
Zajec Projekt i wybór bazy - normalizacja oraz wydajność widoków 12.09.2020, 11:49:17
trueblue 1. Ile obecnie jest tych danych (faktur i pozycji)... 12.09.2020, 12:12:23 
Zajec Cytat(trueblue @ 12.09.2020, 13:12:23... 12.09.2020, 12:31:01
trueblue 1. To tyle co nic. Założone są indeksy na kolumny ... 12.09.2020, 12:37:14 
Zajec Cytat(trueblue @ 12.09.2020, 13:37:14... 12.09.2020, 12:47:40
trueblue Sprawdź jeszcze wynik EXPLAIN SELECT... 12.09.2020, 13:26:05
viking Albo zmień bazę na postgresa, stwórz sobie widok z... 12.09.2020, 13:30:49
Pyton_000 Wywal ten widok i zakoduj zapytanie w aplikacji a ... 12.09.2020, 16:17:47
phpion Nie ma co na siłę trzymać się normalizacji, czasem... 13.09.2020, 08:51:46
Zajec Dzięki wszystkim za odpowiedzi, wątpliwości co do ... 15.09.2020, 21:10:43 ![]() ![]() |
|
Aktualny czas: 24.12.2025 - 13:29 |