Tabela tymczasowa a limit offset?

0

Witam,

Napisalem zapytanie z tabela tymczasowa. Musze pobrac wszystkie zamowienia z dwoch roznych tabel (zaleznie od statusu). Zamowien jest kilk tysiecy. Samo zapytanie jest mi potrzebne do wygenerowania pliku CSV. Wiec przydalo by sie dodac LIMIT OFFSET, zeby nie zabic serwera. Teraz moje pytanie czy to badzie mialo sense? I jak dodac ten limit? Jezeli w tabeli jest tylko kilka dziesia zamowien.

WITH all_orders AS (

    SELECT
        o.order_id  AS order_id,
        o.user_id   AS user_id        
    FROM order o          

    UNION ALL

    SELECT
        ra.order_id       AS order_id,
        ra.user_id        AS user_id      
    FROM ra_orders ra

) SELECT *
  FROM all_orders
  ORDER BY order_id
1
  1. czemu robisz UNION ALL? Sam UNION wywali ci duplikaty (nawet w ramach jednego podselekta)
  2. Możesz zrobić tak:
WITH x as(
 SELECT
        o.order_id  AS order_id,
        o.user_id   AS user_id        
    FROM ORDER o  
LIMIT 100 OFFSET 0
),
y AS(
 SELECT
        ra.order_id       AS order_id,
        ra.user_id        AS user_id      
    FROM ra_orders ra
LIMIT 100 OFFSET 0)
SELECT * FROM y UNION SELECT * FROM x
0

Fakt, zgadzam sie. Tylko te tabele maja bardzo duzo danych. Jezeli wzrosnie limit i offset dosc wysoko to zapytanie x moze nic nie zwracac a y tak. A zapytanie mimo, ze nic nie zwroci dalej bedzie wykonane. Zastanawiam sie czy i tak nie rozbic na dwa zapytania i posortowac wynik po dacie juz w PHP?

0

Nie do końca rozumiem problem, piszesz, że chcesz wyeksportować wszystkie zamówienia, a później mówisz, że jednak nie wszystkie, bo zakładasz LIMIT i OFFSET.
To w końcu jak?

Chcesz wielokrotnie wywoływać to samo zapytanie, tylko z rożnym OFFSETEM ? Czy jednak nie wszystkie zamówienia eksportujesz, a wybranych max 200 ?

1

Jak to nic nie zwróci? Jeśli x lub y cokolwiek zwróci, to UNION również zwróci...

0

Tak, fakt. Ale jezeli limit bedzie np 500 offset np 50000 to zapytanie x moze nie zwrocic nic. Bo po prostu nie bedzie juz rekordow. Ale y moze miec wiecej zapisanych zamowien i jeszcze bedzie zwracac. O co mi chodzi to to, ze po co wykonywac zapytanie na pusto. Jezeli nie ma rekordow to przestac wykonywac zapytanie na tabeli CTE x.

1

OFFSET to zło, którego jeśli możesz, unikaj jak ognia: https://use-the-index-luke.com/no-offset

0

wow, zrobie tak jak w tym artukule. Mam to sens. Dzikie!

0

@hauleth: No offset podejscie powoduje u mnie maly problem. Tego nie widac, tutaj na moim zapytaniu, ale ono ma dosc sporo hierarchie (strukture drzewa), przez co nie mam unikatowych IDkow. Zapytanie wywala np cos takiego:

OrderId TicketId
1 997
1 998
1 999
2 null
2 null
3 996
4 null
5 994
5 994
5 995
6 null
6 null
1

Nadal masz nieunikalne order by, ale wyłuszczę ci w czym rzecz.
masz select :

select orderid, ticketid from tabela order by orderid, ticketid desc limit 8

zwraca ci to to:

OrderId	TicketId
1	999
1	998
1	997
2	null
2	null
3	996
4	null
5	995

Następne zapytanie, by nie uzywać offset konstruujesz tak:

select orderid, ticketid from tabela 
where orderid>5 or (orderid=5 and ticketid<995)
order by orderid, ticketid desc limit 8

wartości 5 i 995, to wartości z ostatniego pobranego rekordu.
ticketid ma być MNIEJSZY, bo zastosowałeś ORDER BY ... DESC na tym polu.

0

Rozumiem o co Ci chodzi. Ale to wcale nie bedzie tak dzialac. Np. Daj limit 2 w pierwszym zapytaniu. Jak dasz orderId > 5 w drugim? :D To zapytanie zwroci rekordy, ktore juz byly wczesniej zwrocone.

Przykladowa tabelka z danymi:

5 null
5 null
5 null
0

To też przez cały czas tłumacze, że masz mieć unikalne order by.

0

Jak bede mial unikalne order by to fakt. Ale ja nie mam i nie wiem jak je uzyskac. Ale pomysl, fakt dobry.

0

Nie masz jakiejś kolumny w stylu id, która jest unikatowa? Jak tak to dodaj ją jako ostatnią wartość do ORDER BY i będziesz miał unikalne sortowanie.

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