2010-02-07 14 views
5

Używam często MySQL, ale zawsze zastanawiałem się dokładnie, jak to działa - kiedy uzyskuję pozytywny wynik, gdzie dokładnie są przechowywane dane? Na przykład, piszę tak:Jak dokładnie działają zapytania bazy danych PHP/MySQL?

$sql = "SELECT * FROM TABLE"; 
$result = mysql_query($sql); 
while ($row = mysql_fetch_object($result)) { 
    echo $row->column_name; 
} 

Gdy wynik jest zwracany, jestem przy założeniu, że trzyma wszystkie wyniki danych, czy też powrócić we fragmencie i zwraca tylko gdzie ona jest proszony o jak $ row- > column_name?

Czy rzeczywiście zwraca każdy pojedynczy wiersz danych, nawet jeśli chcesz uzyskać tylko jedną kolumnę w wyniku $?

Ponadto, jeśli będę używać stronicowania przy użyciu LIMIT, czy ma on TAK oryginalny (stary) wynik, nawet jeśli baza danych jest aktualizowana?

Odpowiedz

8

Szczegóły zależą od implementacji, ale ogólnie mówiąc,, wyniki są buforowane. Wykonanie zapytania w bazie danych zwróci zestaw wyników. Jeśli jest wystarczająco mały, wszystkie wyniki mogą zostać zwrócone wraz z początkowym połączeniem lub niektóre mogą być, a więcej wyników jest zwracanych podczas iteracji nad obiektem wyniku.

Pomyśl o kolejności w ten sposób:

  1. otworzyć połączenie do bazy danych;
  2. Możliwe jest drugie połączenie w celu wybrania bazy danych lub może być wykonane jako część (1);
  3. Ten etap uwierzytelniania i połączenia to (przynajmniej) jedna podróż w obie strony na serwer (ignorowanie trwałych połączeń);
  4. Wykonujesz zapytanie na kliencie;
  5. To zapytanie jest wysyłane na serwer;
  6. Serwer musi określić sposób wykonania zapytania;
  7. Jeśli serwer wcześniej wykonał zapytanie, plan wykonania może nadal znajdować się w pamięci podręcznej zapytań. Jeśli nie, należy stworzyć nowy plan;
  8. Serwer wykonuje zapytanie jako dane i zwraca wynik do klienta;
  9. Wynik ten będzie zawierał bufor wierszy zależny od implementacji. Może to być 100 wierszy lub więcej lub mniej. Wszystkie kolumny są zwracane dla każdego rzędu;
  10. Podczas pobierania kolejnych wierszy klient może poprosić serwer o więcej wierszy. Może to być, gdy klient skończy się lub może być zrobione z wyprzedzeniem. Ponownie jest to zależne od implementacji.

Pomysł tego wszystkiego jest to, aby zminimalizować roundtrips do serwera bez odesłanie zbyt dużo zbędne dane, dlatego jeśli poprosić o milion wierszy nie dostaniesz je wszystkie z powrotem na raz.

Klauzule LIMIT - lub dowolna klauzula - będą modyfikować zestaw wyników.

Wreszcie (7) jest ważna, ponieważ SELECT * FROM table WHERE a = 'foo' i SELECT * FROM table WHERE a = 'bar' są dwa różne pytania miarę optymalizator bazy danych dotyczy więc plan wykonanie musi być określony dla każdego osobno. Ale sparametryzowana kwerenda (SELECT * FROM table WHERE a = :param) o różnych parametrach jest jednym zapytaniem i musi zostać zaplanowana tylko raz (przynajmniej dopóki nie wypadnie z pamięci podręcznej zapytań).

+0

Mam nigdy nie zrozumiał zbyt wiele o tym, jak działają sparametryzowane zapytania. Czy jest to normalny sposób wykonania sparametryzowanej kwerendy, aby wysłać 'SELECT * FROM table WHERE a =: param' do silnika bazy danych wraz z parametrami? Myślałem, że ': param' zostanie zastąpione wartością po stronie klienta. – jnylen

+0

Sparametryzowane zapytanie (ewentualnie przekształcone z biblioteki klienta do tego, co baza rozumie) wraz z parametrem są wysyłane do bazy danych. – cletus

1

Na pierwsze pytanie można odpowiedzieć czytania na resources

Ponieważ jesteś wybierając „*”, każda kolumna jest zwracana dla każdego wywołania mysql_fetch_object. Wystarczy spojrzeć na print_r ($ row), aby zobaczyć.

+1

"Każdy wiersz jest zwracany dla każdego wywołania' mysql_fetch_object'? " Na pewno masz na myśli każdy _kolumnę_. – jnylen

7

Myślę, że mylisz dwa typy zmiennych, z którymi masz do czynienia, a żadna z odpowiedzi nie wyjaśnia tego tak naprawdę.

$result to obiekt wynikowy MySQL. Nie "zawiera żadnych wierszy". Kiedy mówisz: $result = mysql_query($sql), MySQL wykonuje zapytanie i wie, które wiersze będą pasować, ale dane nie zostały przeniesione na stronę PHP. $result może być uważany za wskaźnik do zapytania, które zostało zadane MySQL do wykonania.

Kiedy mówisz $row = mysql_fetch_object($result), wtedy PHP MySQL pobiera dla ciebie wiersz. Tylko ten wiersz jest wstawiany do $row (jako zwykły stary obiekt PHP, ale możesz użyć innej funkcji pobierania, aby poprosić o tablicę asocjacyjną lub określoną kolumnę z każdego wiersza.)

Wiersze mogą być buforowane za pomocą oczekiwanie, że będziesz pobierał wszystkie wiersze w ciasnej pętli (co zwykle ma miejsce), ale generalnie wiersze są pobierane, gdy poprosisz o nie jedną z funkcji mysql_fetch_*.

Jeśli chcesz tylko jedną kolumnę z bazy danych, powinieneś SELECT that_column FROM .... Używanie klauzuli LIMIT jest również dobrym pomysłem, gdy tylko jest to możliwe, ponieważ MySQL może zwykle wykonywać znaczące optymalizacje, jeśli wie, że potrzebujesz tylko określonej grupy wierszy.

0

W prostych słowach zasób zwrócił go jak identyfikator, który biblioteka MySQL kojarzy z innymi danymi. Myślę, że to jest jak karta identyfikacyjna w portfelu, to tylko numer i pewne informacje, ale powiązane z dużo więcej informacji, jeśli dasz je rządowi, firmie telefonicznej itp.

Powiązane problemy