phpMyAdmin
 sql >> Baza danych >  >> Database Tools >> phpMyAdmin

Wybierz rekord tylko wtedy, gdy ten, który ma niższą wartość, trwa zbyt długo i kończy się niepowodzeniem

Oto rozwiązanie Twojego pytania 1, które będzie działać znacznie szybciej, ponieważ masz wiele pełnych skanów tabel i zależnych podzapytań. Tutaj będziesz mieć co najwyżej tylko jedno skanowanie tabeli (i może tabelę tymczasową, w zależności od tego, jak duże są twoje dane i ile masz pamięci). Myślę, że możesz to łatwo dostosować do swojego pytania tutaj. Pytanie 2 (tak naprawdę tego nie czytałem) prawdopodobnie również otrzyma odpowiedź, ponieważ teraz łatwo jest po prostu dodać where date_column = whatever

select * from (
    select
    t.*,
    if(@prev_toner < Remain_Toner_Black and @prev_sn = SerialNumber, 1, 0) as select_it,
    @prev_sn := SerialNumber,
    @prev_toner := Remain_Toner_Black
    from
    Table1 t
    , (select @prev_toner:=0, @prev_sn:=SerialNumber from Table1 order by SerialNumber limit 1) var_init
    order by SerialNumber, id
) sq  
where select_it = 1

EDYCJA:

Wyjaśnienie:

Z tą linią

    , (select @prev_toner:=0, @prev_sn:=SerialNumber from Table1 order by SerialNumber 

po prostu inicjujemy zmienne @prev_toner i @prev_sn w locie. To to samo, co brak tego wiersza w zapytaniu, ale pisanie przed zapytaniem

SET @prev_toner = 0;
SET @prev_sn = (select serialnumber from your_table order by serialnumber limit 1);
SELECT ...

Dlaczego więc zapytanie przypisuje wartość do @prev_sn i dlaczego porządkować według numeru seryjnego? Kolejność według jest bardzo ważna. Bez zamówienia przez nie ma gwarantowanej kolejności zwracania wierszy. Ponadto uzyskamy dostęp do wartości poprzednich wierszy ze zmiennymi, dlatego ważne jest, aby te same numery seryjne były „zgrupowane razem”.

Kolumny w klauzuli select są oceniane jedna po drugiej, dlatego ważne jest, aby najpierw wybrać tę linię

if(@prev_toner < Remain_Toner_Black and @prev_sn = SerialNumber, 1, 0) as select_it,

zanim wybierzesz te dwie linie

@prev_sn := SerialNumber,
@prev_toner := Remain_Toner_Black

Dlaczego? Ostatnie dwie linie przypisują zmiennym tylko wartości bieżących wierszy. Dlatego w tej linii

if(@prev_toner < Remain_Toner_Black and @prev_sn = SerialNumber, 1, 0) as select_it,

zmienne nadal przechowują wartości z poprzednich wierszy. A to, co tutaj robimy, to nic innego jak powiedzenie „jeśli wartość poprzedniego wiersza w kolumnie Remain_Toner_Black jest mniejsza niż w bieżącym wierszu i poprzedni numer seryjny wiersza jest taki sam, jak rzeczywisty numer seryjny wiersza, zwróć 1, w przeciwnym razie zwróć 0."

Następnie możemy po prostu powiedzieć w zewnętrznym zapytaniu „wybierz każdy wiersz, w którym powyższe zwrócono 1”.

Biorąc pod uwagę Twoje zapytanie, nie potrzebujesz wszystkich tych podzapytań. Są bardzo drogie i niepotrzebne. Właściwie to dość szalone. W tej części zapytania

    SELECT  a.ID, 
            a.Time, 
            a.SerialNumber, 
            a.Remain_Toner_Black,
            a.Remain_Toner_Cyan,
            a.Remain_Toner_Magenta,
            a.Remain_Toner_Yellow,
            (
                SELECT  COUNT(*)
                FROM    Reports c
                WHERE   c.SerialNumber = a.SerialNumber AND
                        c.ID <= a.ID) AS RowNumber
    FROM    Reports a

wybierasz całą tabelę i dla każdego wiersza liczysz wiersze w tej grupie. To jest podzapytanie zależne. Wszystko po to, żeby mieć jakiś numer wiersza. Następnie robisz to po raz drugi, aby połączyć te dwie tabele tymczasowe, aby uzyskać poprzedni wiersz. Naprawdę, nic dziwnego, że wydajność jest okropna.

Jak więc dostosować moje rozwiązanie do Twojego zapytania? Zamiast jednej zmiennej, której użyłem do uzyskania poprzedniego wiersza dla Remain_Toner_Black, użyj czterech dla kolorów czarnego, cyjan, magenta i żółtego. I po prostu dołącz do stołu Drukarzy i Klientów, tak jak już to zrobiłeś. Nie zapomnij o zamówieniu do i gotowe.




  1. DBeaver
  2.   
  3. phpMyAdmin
  4.   
  5. Navicat
  6.   
  7. SSMS
  8.   
  9. MySQL Workbench
  10.   
  11. SQLyog
  1. MAMP Pro - aktualizacja problemu z phpMyAdmin

  2. Wyszukaj i zamień „http” na „https” w bazie danych

  3. phpmyadmin - domyślna struktura zamiast przeglądania

  4. Ustawienie pola jako Not NULL w phpmyadmin

  5. Problemy z linkami do bazy danych w interfejsie phpmyadmina