2009-09-10 15 views
9

W Oracle, podczas sprawdzania istnienia wiersza, dlaczego jest Wybierz 1 szybko niż Wybierz licznik (*)?Dlaczego Wybierz 1 szybciej niż Wybierz liczbę (*)?

+1

nie wiedząc, który silnik RDBMS, którego używasz, nie ma sposobu, aby odpowiedzieć poprawnie. Różne silniki zachowują się inaczej – Glen

+1

Czy masz na myśli "dlaczego liczba wybranych elementów (1) jest większa niż Wybierz liczbę (*)"? –

+0

Mam na myśli "Wybierz 1".Patrzę na starą dokumentację standardów kodowania offline, w której twierdzi się, że "Wybierz 1" jest szybszy niż "Wybierz liczbę (*)" i preferowany sposób sprawdzania istnienia wiersza. Dokumentacja nie zawiera technicznego wyjaśnienia, dlaczego jest to technika "zwiększania wydajności". Kiedy szukałem w sieci, znalazłem rzeczy takie jak wątki i dyskusje w AskTom ... ale nie widziałem jasnej, ostatecznej odpowiedzi. –

Odpowiedz

14

Od Oracle nie obsługuje IF EXISTS w PL/SQL, sugestia CodeByMidnight do korzystania EXISTS normalnie zrobić coś jak

SELECT 1 
    INTO l_local_variable 
    FROM dual 
WHERE EXISTS( 
    SELECT 1 
     FROM some_table 
    WHERE some_column = some_condition); 

Oracle wie, że może zatrzymać przetwarzanie WHERE EXISTS klauzuli jak najszybciej znaleziono jeden wiersz, więc nie musi potencjalnie liczyć dużej liczby wierszy spełniających kryteria. Oczywiście nie jest to problemem, jeśli sprawdzasz, czy wiersz z określonym kluczem istnieje, czy sprawdzasz warunek związany z niepotwierdzonymi kolumnami, czy sprawdzasz warunek, który może spowodować zwrócenie dużej liczby wierszy.

(Uwaga: chciałbym móc opublikować to jako komentarz do posta CodeByMidnight, ale komentarze nie mogą zawierać sformatowanego kodu).

UPDATE: Biorąc pod uwagę wyjaśnienia oryginalny plakat wykonany w swoim komentarzu, krótki, ostateczna odpowiedź jest taka, że ​​SELECT 1 lub SELECT COUNT(1) nie szybciej niż SELECT COUNT(*) jest. Wbrew wszelkim wskazówkom dotyczącym kodowania, preferowanym sposobem zliczania wszystkich wierszy jest COUNT(*). Był stary mit, że COUNT(1) był szybszy. To przynajmniej nie było prawdą w żadnej wersji Oracle wydanej w ciągu ostatniej dekady i jest mało prawdopodobne, że kiedykolwiek była prawdziwa. Było to jednak powszechne przekonanie. Dzisiaj kod, który ma numer COUNT(1), a nie COUNT(*) generalnie sprawia, że ​​podejrzewam, że autor jest skłonny wierzyć w różne mity Oracle, dlatego sugerowałbym użycie COUNT(*).

0

Ponieważ gwiazda bierze wszystkie kolumny do liczby, "1" jest rodzimym typem danych.

W MySQL "SELECT COUNT (name_of_the_primary_key)" powinno być tak szybkie, jak SELECT 1. Jest to indeks, który się liczy. Liczenie() w indeksie powinna być dość szybko;)

2

Byłbym zaskoczony, jeśli wybrana liczba (*) nie została odpowiednio zoptymalizowana, nie ma potrzeby ładowania we wszystkich kolumnach, ponieważ nie będzie przetwarzania związanego z kolumną.

+1

tak. Oracle traktuje count (*) dokładnie tak samo jak count (1), count (null), count ("dowolna wartość atomowa, którą lubisz"). –

15

Lepiej nadal używać EXISTS, gdy obsługuje go RDBMS lub odpowiednik, ponieważ spowoduje to zatrzymanie przetwarzania wierszy, gdy tylko znajdzie dopasowanie.

+5

+1 Powinniśmy używać tylko COUNT(), musimy znać faktyczną liczbę rekordów. – APC

0

Wszystkie inne rzeczy są równe, "select 1 from my_table" zwróci wynik pierwszy szybciej niż "select count(*) from my_table", ale jeśli pobrać wszystkie wyniki kwerendy, jeden count(*) będzie szybciej, ponieważ wymaga znacznie mniej danych (1 całkowitą, jak w przeciwieństwie do 1 liczby całkowitej na każdy wiersz w tabeli).