CREATE VIEW - czy to jest optymalne?

Odpowiedz Nowy wątek
2011-10-25 22:07
0

Witam. Mam taką tabelę

id data
4444 firstdata
4444 second
4444 costamcostam
3333 wsiump
3333 tralala
4444 firstdata

No i sobie ją pobieram.
SELECT * FROM TABLE.
Następnie w PHP przetwarzam sobie tę dane w PHP - grupuję dane poprzez ID.

Lecz problem następuje gdy chcę zrobić pager na stronię, czyli wyświetlać od 0 do 30 rekordów.
Czyli tak jakby użyć zapytania

SELECT * FROM table WHERE ID IN ( SELECT id FROM table GROUP BY id LIMIT 0, 30);

I myślę że w moim przypadku to będzie nie optymalne - moje zapytanie jest zbyt szeczgółowe ( http://4programmers.net/Pastebin/1373 ), to tak jaby 2 te same zapytanie wykonać - myślę że MySQL nie wyrobi.

Dlatego myślę o alternatywie.
Myślę by zrobić
CREATE VIEW tmpview AS SELECT * FROM TABLE;

Następnie by pobrać dane
SELECT * FROM tmpview WHERE id IN (SELECT id FROM tmpview GROUP BY id LIMIT 0,30)

Czy to jest dobre i optymalne rozwiązanie? Czy create view jest dłuższe od podwójnego zapytania o ten sam szczegół?


:)

Pozostało 580 znaków

2011-10-25 22:33
1
  1. można wiedzieć po co te dwa podzapytania i in? - wyciągnij z nich warunki "do góry"
  2. jak zrobisz widok to to nie przyśpieszy/zwolni zapytania, jedynie je uprości

- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2011-10-25 22:39
0
SELECT * FROM table  /* tutaj wybieram rekordy, Nie moge do tego dać zapytania GROUP BY id bo usunie dane, gdzie kolumna data ma inną wartość */

WHERE ID IN ( SELECT id FROM table GROUP BY id LIMIT 0, 30); /* tutaj już grupuję przez ID, po to by pobrać ile jest faktycznych wyników, gdzie jest unikalne ID. Następnie daje LIMIT 0, 30)*/

Man nadzieje że teraz rozumiesz. Jeśli nie o to chodziło, to podaj przykład zapytania/ pseudo zapytanie ... będę wdzięczny.


:)

Pozostało 580 znaków

2011-10-25 22:41
0

Po co robisz podzapytanie? Po co robisz grupowanie? Po co widok z gwiazdką z jednej tabeli? Dlaczego LIMIT nie dasz od razu po swoim zapytaniu?

Widok służy do wyświetlania tylko wybranych kolumn zazwyczaj z kilku tabel, bez konieczności ich wybierania po poleceniu SELECT. Czyli innymi słowy ma zadanie ukryć szczegółową implementację, która może być skomplikowana. Widok nic nie przyspiesza. Zapytanie wykonane na widoku niczym nie różni się od wykonania na tabeli... z wyjątkiem tego, że na widoku wykona się nieco wolniej.

/edit: w tabeli nie masz unikalnych id? Jeżeli nie chcesz żeby Ci czegoś usunęło w tym group by to dodaj te pole do group by, wtedy nie będziesz musiał robić podzapytania.

edytowany 2x, ostatnio: AdamPL, 2011-10-25 22:49

Pozostało 580 znaków

2011-10-25 22:48
0
AdamPL napisał(a)

Po co robisz podzapytanie? Po co robisz grupowanie? Po co widok z gwiazdką z jednej tabeli? Dlaczego LIMIT nie dasz od razu po swoim zapytaniu?

Widok służy do wyświetlania tylko wybranych kolumn zazwyczaj z kilku tabel, bez konieczności ich wybierania po poleceniu SELECT. Czyli innymi słowy ma zadanie ukryć szczegółową implementację, która może być skomplikowana. Widok nic nie przyspiesza. Zapytanie wykonane na widoku niczym nie różni się od wykonania na tabeli... z wyjątkiem tego, że na widoku wykona się nieco wolniej.

O to serwer testowy:
phpmyadmin: http://phpmyadmin.bordeux.net/
user: bordeux_test
pass: test

Proszę wykonać zapytanie:

SELECT 
    * 
FROM  
    `auctions`  
LEFT JOIN 
    `fields_values`
ON 
    `fields_values_auction` = `auctions_id`
LEFT JOIN 
    `fields`
ON 
    `fields_id` = `fields_values_ids`
WHERE 
    `auctions_category`
        LIKE 
    "/%"
AND
    `auctions_id` 
        IN 
            (   
                SELECT 
                    `fields_values_auction`
                FROM 
                    `fields_values`
                LEFT JOIN 
                    `fields`
                ON
                    `fields_values_ids` = `fields_id`
                WHERE
                    `fields_name` = "cost"
                AND
                    `fields_values_val` > 2000  
            )
AND
    `auctions_id` 
        IN 
            (   
                SELECT 
                    `fields_values_auction`
                FROM 
                    `fields_values`
                LEFT JOIN 
                    `fields`
                ON
                    `fields_values_ids` = `fields_id`
                WHERE
                    `fields_name` = "miasto"
                AND
                    `fields_values_val` = "katowice"
            )

I muszę zrobić do tego LIMIT, by zrobić pagger na stronie. auction_id to jest id aukcji... a może ich być nawet milion.


:)
edytowany 1x, ostatnio: bordeux, 2011-10-25 22:52

Pozostało 580 znaków

2011-10-25 22:52
0

Pola, które pobierasz w SELECT wstaw do group by i wtedy zrób limit już bez podzapytania i sprawdź co się szybciej wykona.

Pogrupowanie po tych polach może trwać dłużej niż wykonanie podzapytania, więc musisz to sprawdzić.

Pozostało 580 znaków

2011-10-25 23:03
0

Nie za bardzo rozumiem, o to chodziło?


SELECT 
        *
FROM  
        `auctions`  
LEFT JOIN 
        `fields_values`
ON 
        `fields_values_auction` = `auctions_id`
LEFT JOIN 
        `fields`
ON 
        `fields_id` = `fields_values_ids`
WHERE 
        `auctions_category`
                LIKE 
        "/%"
AND
        `auctions_id` 
                IN 
                        (        
                                SELECT 
                                        `fields_values_auction`
                                FROM 
                                        `fields_values`
                                LEFT JOIN 
                                        `fields`
                                ON
                                        `fields_values_ids` = `fields_id`
                                WHERE
                                        `fields_name` = "cost"
                                AND
                                        `fields_values_val` > 2000        
                        )
AND
        `auctions_id` 
                IN 
                        (        
                                SELECT 
                                        `fields_values_auction`
                                FROM 
                                        `fields_values`
                                LEFT JOIN 
                                        `fields`
                                ON
                                        `fields_values_ids` = `fields_id`
                                WHERE
                                        `fields_name` = "miasto"
                                AND
                                        `fields_values_val` = "katowice"
                        )
    GROUP BY auctions_id, auctions_category, auctions_views,    fields_values_id, fields_values_ids, fields_values_val, fields_values_auction, fields_id,   fields_category,    fields_name,    fields_search,  fields_search_options, fields_type, fields_priority
LIMIT 0, 2;

Jeśli tak, to pokazują się 2 rekordy - a aukcja ma więcej niż 2 pola.


:)

Pozostało 580 znaków

2011-10-26 00:04

bez in

SELECT 
  *
FROM  
  auctions a
LEFT JOIN fields_values v ON v.fields_values_auction = a.auctions_id
LEFT JOIN fields f ON f.fields_id = v.fields_values_ids
JOIN (
  SELECT 
    fields_values_auction
  FROM 
    fields_values v 
  LEFT JOIN fields f ON f.fields_id = v.fields_values_ids
  WHERE 
    (f.fields_name = "cost" AND v.fields_values_val > 2000)
    OR (f.fields_name = "miasto" AND v.fields_values_val = "katowice")
  group by 
    fields_values_auction
  having 
    count(fields_values_auction) = 2) x on x.fields_values_auction = a.auctions_id
WHERE 
  auctions_category LIKE "/%"

albo zamiast dwóch in możesz mieć jedno (to jest tylko podzapytanie, reszta jak w Twoim zapytaniu

SELECT 
  fields_values_auction
FROM  
 fields_values v 
LEFT JOIN fields f ON f.fields_id = v.fields_values_ids
WHERE 
  (f.fields_name = "cost" AND v.fields_values_val > 2000)
  OR (f.fields_name = "miasto" AND v.fields_values_val = "katowice")
group by 
  fields_values_auction
having 
  count(fields_values_auction) = 2

Oczywiście jeśli będziesz miał 3 warunki to having musi być = 3

Który wybrać - musisz sprawdzić który będzie szybszy.

I taka subiektywna uwaga ode mnie - używaj aliasów dla tabel i poprzedzaj nimi nazwę pola. Wiem, że Ty pewnie znasz tą bazę na pamięć ale jak ktoś nie wie gdzie jakie pole jest to mu trudno się poruszać w zapytaniu


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij
edytowany 2x, ostatnio: Misiekd, 2011-10-26 01:31
Co do aliasów do tabel - przecież takie coś jest. Ostatni znak _ rozdziela nazwę tabeli od nazwy pola, np fields_values_auction oznacza tabele fields_values, pole auction z tej bazy. auctions_category - oznacza tabele auctions , pole category ;] - bordeux 2011-10-26 15:00
^^^ z tej tabeli (nie z bazy tak jak napisałem) - bordeux 2011-10-26 15:01
może ja jakiś inny jestem ale jak mam pole np. product_id to w KAŻDEJ tabeli ono się ma nazywać product_id i być tego samego typu a nie np. auctions_product_id czy inaczej. - Misiekd 2011-10-26 16:02

Pozostało 580 znaków

2011-10-26 01:18
0

Podziękuj pięknie Miśkowi (piwo wskazane), bo odwalił za Ciebie kawał roboty. Mnie te formatowanie odrzuciło od jakichkolwiek prób przeczytania ze zrozumieniem.

jak wkleiłem to do phpmyadmina to też miałem ochotę to olać :p no ale jak się powiedziało a to trzeba było powiedzieć b - Misiekd 2011-10-26 01:27

Pozostało 580 znaków

2011-10-26 08:12
0

Wielkie podziękowania Misiekd! Już n'ty raz mi pomogłeś w trudnych dla mnie zapytaniach. Jeszcze raz, wielkie podziękowanie!


:)

Pozostało 580 znaków

2011-10-26 11:08
1

tak jak pisałem wcześniej - zrób najpierw testy i zobacz jak wygląda execution plan bo może się okazać, że jednak Twoje zapytanie jest lepsze. Sprawdź dla małej ilości kryteriów i dla większej.
BTW czy jest coś co pokaże execution plan mysqla jakoś normalnie :p


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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