[ Pobierz całość w formacie PDF ]
.To prawda, ale czasami trzeba poświęcić zasadyw imię uzyskania większej wydajności.Równoczesne wykonywanie poleceń SELECT i UPDATE w tej samej tabeliBaza danych MySQL nie pozwala na wykonywanie polecenia SELECT względem tabeli, naktórej jednocześnie jest wykonywane polecenie UPDATE.Naprawdę nie jest to ograniczeniewynikające z optymalizatora, ale wiedza o sposobie wykonywania zapytań przez MySQLmoże pomóc w obejściu tego problemu.Poniżej przedstawiono przykład niedozwolonegozapytania, mimo że jest standardowym kodem SQL.Zapytanie powoduje uaktualnienie każdegorekordu liczbą podobnych rekordów znajdujących się w tabeli:mysql> UPDATE tbl AS outer_tbl-> SET cnt = (-> SELECT count(*) FROM tbl AS inner_tbl-> WHERE inner_tbl.type = outer_tbl.type-> );ERROR 1093 (HY000): You can't specify target table 'outer_tbl' for update in FROMclauseAby obejść to ograniczenie, można wykorzystać tabelę pochodną, ponieważ MySQL potrak-tuje ją jak tabelę tymczasową.W ten sposób faktycznie zostaną wykonane dwa zapytania:pierwsze to SELECT w podzapytaniu, drugie obejmuje wiele tabel UPDATE z połączonymi wy-nikami tabeli oraz podzapytania.Podzapytanie będzie otwierało i zamykało tabelę przedotworzeniem jej przez zewnętrzne zapytanie UPDATE, a więc całe zapytanie będzie mogłozostać wykonane:mysql> UPDATE tbl-> INNER JOIN(-> SELECT type, count(*) AS cnt-> FROM tbl-> GROUP BY type-> ) AS der USING(type)-> SET tbl.cnt = der.cnt;Optymalizacja określonego rodzaju zapytańW podrozdziale zostaną przedstawione wskazówki dotyczące optymalizacji określonego ro-dzaju zapytań.Większość tych zagadnień została szczegółowo omówiona w innych częściachksiążki, ale autorzy chcieli utworzyć listę najczęściej spotykanych problemów optymalizacji,do której można łatwo powracać.Większość wskazówek przedstawionych w podrozdziale jest uzależniona od wersji serwerai może być nieaktualna w przyszłych wersjach MySQL.Nie ma żadnego powodu, aby pew-nego dnia sam serwer nie uzyskał możliwości przeprowadzania niektórych bądz wszystkichz wymienionych optymalizacji.Optymalizacja określonego rodzaju zapytań | 207 Optymalizacja zapytań COUNT()Funkcja agregująca COUNT() i sposób optymalizacji zapytań wykorzystujących tę funkcję toprawdopodobnie jeden z dziesięciu najbardziej niezrozumiałych tematów w MySQL.Liczbabłędnych informacji na ten temat, które autorzy znalezli w Internecie, jest większa, niż możnasądzić.Przed zagłębieniem się w zagadnienia optymalizacji bardzo ważne jest zrozumienie, jak działafunkcja COUNT().Jakie jest działanie funkcji COUNT()?COUNT() to funkcja specjalna działająca na dwa odmienne sposoby: zlicza wartości oraz rekordy.Wartość jest wyrażeniem innym niż NULL (ponieważ NULL oznacza brak wartości).Jeżeliw nawiasie zostanie podana nazwa kolumny lub inne wyrażenie, funkcja COUNT() obliczy, ilerazy podane wyrażenie ma wartość.Dla wielu osób będzie to bardzo mylące, co po częściwynika z faktu, że same wartości NULL są mylące.Jeżeli czytelnik musi nauczyć się, jak działaSQL, warto sięgnąć pod dobrą książkę omawiającą podstawy SQL.(Internet niekoniecznie jestdobrym zródłem informacji na ten temat).Inna forma funkcji COUNT() po prostu oblicza liczbę rekordów w wyniku.Jest to sposób działaniabazy danych MySQL, kiedy wie, że wyrażenie umieszczone w nawiasie nigdy nie będzie NULL.Najbardziej oczywistym przykładem jest polecenie COUNT(*) będące specjalną formą funkcjiCOUNT().Nie powoduje ona rozszerzenia znaku wieloznacznego * na pełną listę kolumn w tabeli,jak można by tego oczekiwać.Zamiast tego całkowicie ignoruje kolumny i zlicza rekordy.Jednym z najczęściej popełnianych błędów jest podawanie w nawiasie nazw kolumn, kiedyprogramista chce, aby funkcja zliczyła rekordy.Gdy trzeba obliczyć liczbę rekordów w wy-niku, wtedy zawsze należy użyć funkcji COUNT(*).Taka postać jasno wskazuje intencje pro-gramisty i pozwala uniknąć kiepskiej wydajności.Mity dotyczące MyISAMCzęsto popełnianym błędem jest przeświadczenie, że silnik MyISAM jest wyjątkowo szybkipodczas wykonywania zapytań COUNT().Wprawdzie jest szybki, ale tylko w wyjątkowejsytuacji: kiedy stosujemy funkcję COUNT(*) bez klauzuli WHERE, która po prostu zlicza liczbęrekordów w całej tabeli.Baza danych MySQL może zoptymalizować to zapytanie, ponieważsilnik magazynu danych zawsze otrzymuje informację, ile rekordów znajduje się w tabeli.Jeżeli w MySQL określono, że col nigdy nie przyjmie wartości NULL, wówczas można rów-nież zoptymalizować wyrażenie COUNT(col) poprzez wewnętrzną konwersję wyrażeniana COUNT(*).Silnik MyISAM nie ma żadnych magicznych optymalizacji dotyczących zliczania rekordów,kiedy zapytanie używa klauzuli WHERE lub dla bardziej ogólnych przypadków zliczaniawartości zamiast rekordów.W określonym zapytaniu może działać szybciej niż inne silnikimagazynu danych, ale nie musi.Wszystko zależy od wielu czynników.208 | Rozdział 4.Optymalizacja wydajności zapytań Prosta optymalizacjaCzasami można wykorzystać zalety optymalizacji MyISAM w postaci COUNT(*) do zliczeniawszystkiego, z wyjątkiem małej liczby rekordów, które zostały doskonale zindeksowane.W przedstawionym poniżej przykładzie użyto standardowej bazy danych World w celu po-kazania, jak można efektywnie znalezć liczbę miast, których identyfikator ID jest większy niż 5.Takie zapytanie można zapisać następująco:mysql> SELECT COUNT(*) FROM world.City WHERE ID > 5;Jeżeli powyższe zapytanie zostanie sprofilowane za pomocą polecenia SHOW STATUS, możnaprzekonać się, że zapytanie przeskanowało 4079 rekordów [ Pobierz całość w formacie PDF ]

Archiwum