2013-07-22 13 views
5

Mam dwie tabele:GROUP BY za pomocą klucza obcego lub klucza podstawowego?

user 
======= 
id 
name 
class 

marks 
======= 
id 
user_id 
sub_id 
mark 

stół użytkownika zawiera szczegółowe informacje dotyczące użytkownika (student) znaki tabela zawiera znamiona student w różnych przedmiotów o ID przedmiotu

chcę sprowadzić imię, klasa i suma ocen z tych tabel.

Mam dwa pytania:

1. SELECT name, class, SUM(mark) AS total FROM user 
    LEFT JOIN marks ON marks.user_id = user.id 
    GROUP BY marks.user_id 
    ///Here in GROUP BY I have used foreign key (marks.user_id) 

2. SELECT name, class, SUM(mark) AS total FROM user 
    LEFT JOIN marks ON marks.user_id = user.id 
    GROUP BY user.id 
    ///Here in GROUP BY I have used primary key (user.id) 

Zarówno daje mi potrzebne dane. Moje pytanie brzmi: z którego należy korzystać?

Czy istnieje jakaś reguła, która mówi, że należy użyć klucza podstawowego w grupie przez LUB klucz obcy w grupie przez LUB coś w tym stylu?

+1

spróbuj uruchomić zapytanie, którego 'user.id' nie ma pasującej wartości dla' marks.user_id'. i zobacz, co się stanie .. –

+2

Co mówi "Wyjaśnij" o obu zapytaniach? –

+0

@ 491243: Pozwól mi to sprawdzić. –

Odpowiedz

3

Powinieneś użyć grupy wersji 2 według klucza podstawowego. Generalnie lepiej jest mieć porządek i grupę według instrukcji opartych na kolumnach tabeli głównej, a nie na połączonych. Jeśli zamawiasz lub grupujesz według połączonych kolumn tabeli, MySQL musi utworzyć tymczasowe tabele, które w oparciu o Twoją bazę danych mogą łatwo przejść na dysk i doprowadzić do znacznego ograniczenia wydajności.

uruchomić te wyjaśnia na dwa zapytania, aby zobaczyć co mi chodzi:

EXPLAIN SELECT name, SUM(mark) AS total FROM users 
    LEFT JOIN marks ON marks.user_id = users.id 
    GROUP BY marks.user_id; 

EXPLAIN SELECT name, SUM(mark) AS total FROM users 
    LEFT JOIN marks ON marks.user_id = users.id 
    GROUP BY users.id; 

samo można znaleźć tutaj: http://sqlfiddle.com/#!2/a8ece/6

+0

Dzięki, myślę, że to jest odpowiedź, której potrzebowałem. :) –

0

ponieważ klucz podstawowy jest unikalnym indeksem. grupa przez (klucz podstawowy)

nie zmniejsza się liczbę linii w wyniku

więc myślę, że można użyć grupę przez (klucz obcy)

6

Biorąc zrobiliście w lewo dołączyć należy użyć Druga kwerenda jako marks.user_id może być pusta

+0

A co, jeśli marks.user_id nie ma wartości null. Mówię o występie, kiedy będę miał ogromne dane. –

2

Ostrożnie sugeruję, aby użyć drugiej, ponieważ istnieje niewielka różnica w wydajności między indeksem klucza podstawowego a dowolnym innym zduplikowanym indeksem. Jest bardzo prawdopodobne, że najczęstszym zapytaniem do tej tabeli będzie ustalenie, czy użytkownik ma określone oznaczenia, a zapytanie będzie działać szybko, chyba że znacznik markss.user_id może mieć wartość null.

1

Kiedy wpadłem następujące SQL:

DESCRIBE SELECT name, class, SUM(mark) AS total FROM user 
LEFT JOIN marks ON marks.user_id = user.id 
GROUP BY marks.user_id; 

MySQL powiedział, że używa fileort do tabeli użytkownika i nie użyto żadnych klawiszy do tabeli, a kiedy uruchomiłem:

DESCRIBE SELECT name, class, SUM(mark) AS total FROM user 
LEFT JOIN marks ON marks.user_id = user.id 
GROUP BY user.id; 

Teraz MySQL powiedział, że używa kluczy dla obu tabel (zamiast używania filesort). Dlatego uważam, że druga powinna być zalecaną praktyką, ponieważ pliki mogą pogarszać wydajność.