Există vreo diferență între aceste interogări SQL?

ei fac același lucru, dar aș vrea să știu dacă există vreo diferență, vreau să spun despre performanță ...

TB1: tb1_id -> PK ...

TB2: tb1_id -> FK ...

select columns ... from tb1 a left join tb2 b
    on a.tb1_id=b.tb1_id and b.uid=xxxxxxx where a.tb1_id=yyy limit 1

select columns ... from tb1 a left join tb2 b
    on a.tb1_id=b.tb1_id where a.tb1_id=yyy and b.uid=xxxxxxx limit 1

Mulțumiri.

1

4 răspunsuri

Simplificând puțin lucrurile, puteți considera că codul JOIN s este evaluat mai întâi și apoi sunt aplicate filtrele WHERE s. Folosind această formulă:

1) Prima dvs. interogare va returna toate înregistrările din tabelul a și înregistrările corespunzătoare din tabelul b (dacă există, altfel un set de NULL < care au un tb1_id și o anumită valoare în câmpul uid . Setul rezultat va fi apoi filtrat pentru a avea doar înregistrări cu a.tb1_id = yyy , iar prima înregistrare va fi returnată clientului.

2) A doua interogare va returna toate înregistrările din tabelul a și înregistrările corespunzătoare din tabelul b (dacă există, altfel un set de NULL < care au o potrivire tb1_id . Setul rezultat va fi filtrat pentru a avea numai înregistrări care au o anumită valoare în a.tb1_id , precum și o anumită valoare în b.uid . Ultima parte este importantă. Această condiție particulară va elimina toate acele înregistrări din tabelul a care nu are un set de potrivire în b doar pentru că NULL! = Xxxxxxx . În esență, nu combinați LEFT JOIN cu o condiție "greu" în WHERE . Când faceți acest lucru, vă transformați imediat codul OUTER într-un INNER unul . Prima înregistrare a setului rămas va fi returnată clientului.

Acestea fiind spuse, s-ar putea să se întâmple așa că, în cazul tău, ai putea obține același rezultat. Întâmplător. Nu aveți un ORDER BY în interogări dvs., astfel încât ordinea de înregistrări returnate este de până la motorul de baze de date (esti mai bine de gândire nu este deterministă și nu pot fi invocate, pur și simplu foarte probabil este atât oricum) și tocmai se poate întâmpla, astfel încât prima înregistrare returnat de ambele interogări este cel care se potrivesc toate condițiile - are tb1_id meci în a și b , precum și xxxxxxx în b.uid .

2
adăugat

După ce nu am observat partea "STÂNGA" a legăturii, am îndoit de răspunsul meu inițial. După câteva cercetări rapide, am revizuit răspunsul meu.

Acest articol explică lucrurile în detaliu, arătând că interogările sunt tratate în mod diferit.

Acest lucru este arătat cu un exemplu din articolul de mai jos.

mysql> SELECT * FROM product LEFT JOIN product_details
   ON (product.id = product_details.id)
   AND product_details.id=2;
+----+--------+------+--------+-------+
| id | amount | id   | weight | exist |
+----+--------+------+--------+-------+
|  1 |    100 | NULL |   NULL |  NULL |
|  2 |    200 |    2 |     22 |     0 |
|  3 |    300 | NULL |   NULL |  NULL |
|  4 |    400 | NULL |   NULL |  NULL |
+----+--------+------+--------+-------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM product LEFT JOIN product_details
   ON (product.id = product_details.id)
   WHERE product_details.id=2;
+----+--------+----+--------+-------+
| id | amount | id | weight | exist |
+----+--------+----+--------+-------+
|  2 |    200 |  2 |     22 |     0 |
+----+--------+----+--------+-------+
1 row in set (0.01 sec)
1
adăugat

Nu sunt aceleași. Vedeți răspunsul oferit de @Pavel_Veller Aceasta este doar în sprijinul răspunsului său. Fugiți pe Postgres:

create table tb1( tb1_id int );
create table tb2( tb1_id int, uid int );

insert into tb1 values( 1 );

insert into tb2 values( 1, 0 );

select a.tb1_id
  from tb1 a left join tb2 b on a.tb1_id = b.tb1_id and b.uid = 3
  where a.tb1_id = 1;

select a.tb1_id
  from tb1 a left join tb2 b on a.tb1_id = b.tb1_id
  where a.tb1_id = 1
    and b.uid = 3;

Rezultate:

postgres=#     select a.tb1_id
postgres-#       from tb1 a left join tb2 b on a.tb1_id = b.tb1_id and b.uid = 3
postgres-#       where a.tb1_id = 1;
 tb1_id
--------
      1
(1 row)


postgres=#     select a.tb1_id
postgres-#       from tb1 a left join tb2 b on a.tb1_id = b.tb1_id
postgres-#       where a.tb1_id = 1
postgres-#         and b.uid = 3;
 tb1_id
--------
(0 rows)
1
adăugat

aceste două interogări nu fac deloc același lucru, primul nu ar putea să returneze rânduri de la b, în ​​timp ce al doilea nu va returna nici unul de la a și b dacă nu există o conexiune validă cu b.

Mysql interpretează "=" în clauza unde se situează ca și cum ar fi un INNER join (nu este un join, dar este folosit în același mod în acest caz)

0
adăugat
MySQL - comunitatea Română
MySQL - comunitatea Română
19 participanți

Comunitatea română a programatorilor MySQL.