[Oracle SQL] Szybkość =, like, in


(Marcin Obala) #1

Witam

Pracuję aktualnie z bazą danych Oracle ale zapewne tą przypadłość mają również inne odmiany SQL. Problem polega na szybkości. Przykładowo

select *

from test

where col1 in ('Tekst', 'Tekst2')

Działa znacznie wolniej niż poniższe dwa zapytania niżej.

select *

from test

where col1 = 'Tekst'

select *

from test

where col1 = 'Tekst2'

Skąd to się bierze? Nie znam mechanizmów wyszukiwania danych w tabelach ale na chłopski rozum w drugim wypadku po prostu sprawdzam czy col1 ma odpowiednią wartość i wyświetlam, następnie drugie zapytanie. Co daje nam dwa porównania na każdym rekordzie. Przy in nie powinno być tak samo? Po prostu sprawdza czy col1 równa się którejś z wartości w nawiasie? Co daje nam również dwa porównania na rekord. W kodzie musiałem zastosować taki myk

foreach (string line in BarcodeRichTextBox.Lines)

{

	DataTable dt = new DataTable();

	command = new OracleCommand(query.Replace("paste_here",line), con);

	reader = command.ExecuteReader();

	dt.Load(reader);

	allData.Merge(dt);

}

(kostek135) #2

Nie wiem czy używasz stałych napisowych czy podzapytań (uprościłeś przykład, a ma to zapewne znaczenie). Dla stałych napisowych nie mam pojęcia, dla podzapytań dlatego, że podzapytanie jest wykonywane jako pierwsze przy użyciu IN. Btw. A nie będzie lepiej wszystkie warunki z OR-ować w zapytaniu zamiast łączyć po stronie aplikacji?


(Marcin Obala) #3

Nic nie uprościłem, patrz kod wyżej. W richtextboxie są wartości w każdej linijce do wyszukania, nie korzystam z podzapytań. A rzeczywiście, tak jak Ty mówisz mogę w pętli po prostu wygenerować warunki z OR dla Where. Ja wyżej zrobiłem to w ten sposób że dla każdej linijki wczytuję dane a następnie je łączę w tabeli.


(kostek135) #4

Rozumiem, nie mam więc pojęcia czemu dla stałych napisowych działa w ten sposób. Generalnie nie wiem czy w Oraclu jest dostęp do zapytania, które zostało przerobione przez optymalizator (bo w tym wypadku to będzie miało największy wpływ na czas wybierania danych), pamiętam, że w Transact SQL było, może i tu jest.

Mam jeszcze jedną teorię. Nie wiem ile masz danych w tej tabeli, ale jeśli mało IN może np. korzystać z indeksów przy szukaniu odpowiednich wartości co dla małych tabel jest beznadziejne.

Tak czy siak IN zaleca się stosować przy podzapytaniach kiedy tabele na których działają są relatywnie małe do tabeli na której będzie działać zapytanie główne.


(Marcin Obala) #5

W tabeli jest wiele tysięcy, jak nie dziesiąt czy set tysięcy rekordów. Jak daję = wynik czyli jakieś 300 rekordów mam w sekundę, dwie, jak daję IN gdzie w nawiasie jest jedna wartość (‘Tekst1’) to też bardzo szybko natomiast jak dam dwie wartości to mogę iść zrobić herbatę.