2012-10-18 14 views
11

Mamy tabelę zawierającą ponad dwa miliony wierszy, w której wszystkie zapytania związane z nią to między wyszukiwaniem z użyciem Column1 i Column2. Ponadto będzie tylko jeden możliwy wynik. Na przykład ...Indeksowanie SQL dla zapytania z tylko jednym dopasowaniem?

Col1  Col2 
1  5 
6  10 
11  15 

select * from table1 where 8 between Col1 and Col2 

obecnie mam unikalnego indeksu klastrowego na Col1 i Col2. Do tej pory nie byłem w stanie dowiedzieć się, jak dalej dostroić zapytanie i indeksy, aby zminimalizować liczbę obsługiwanych wierszy. Plan wykonania przedstawia obecnie koszt prawie 0,5 i 113 tys. Wierszy obsługiwanych podczas lokalizowania jedynej poprawnej odpowiedzi.

Jakie opcje mogę pominąć?

Zgodnie z wnioskiem, dane z aktualnego planu wykonania:

Operation 
Clustered Index Seek 
Predicate 
CONVERT_IMPLICIT(bigint,[@2],0)<=[Col2] 
Seek Predicate 
Seek Keys[1]: End: Col1 <= Scalar Operator(CONVERT_IMPLICIT(bigint,[@1],0)) 
+0

Czy pomożecie napisać to jako "wybierz * z tabeli 1, gdzie Col1 = < 8 and Col2> = 8 ' – Vicki

+0

Czy krok zawsze wynosi 5 w Col1? Jeśli tak, to odpowiedź jest prosta :) –

+0

Jak wygląda plan wykonania? Czy możesz dodać to do pytania? –

Odpowiedz

3

Myślę, że znalazłem odpowiedź. Musiałem zacząć od stworzenia unikalnego indeksu klastrowego na Col1, a następnie utworzyć unikalny indeks nieklastrowy na Col2. Zapytanie następnie musiało zostać zaktualizowane, aby wymusić wyszukiwanie w każdym Indeksie.

select * from table1 where Col1 = 
    (select max(Col1) from table1 where Col1 <= 8) 
and Col2 = 
    (select min(Col2) from table1 where Col2 >= 8) 

Plan wykonania zawiera teraz 0,0098 kosztu i 1 wiersza przetwarzanego.

1
select * from table1 where Col1 <= 8 and Col2 >= 8 

Może „pomiędzy” dwoma kolumnami jest przyczyną problemu.

Ponadto, powinieneś mieć tylko jeden złożony indeks na obu kolumnach (Col1, Col2).

6

Czy zakresy zawsze się nie pokrywają? Wspomniałeś, że zawsze jest tylko jeden mecz. Jeśli są, można zapisać go jako:

SELECT * FROM table1 
    WHERE 8 <= Col2 
    ORDER BY Col2 ASC 
    LIMIT 1 

To daje wiersz o najniższej wartości Col2 która jest powyżej 8 - który to zakres jesteś zainteresowany Indeks byłaby potrzebna tylko. Col2, a koszt powinien być mały.

Ponieważ nie wspomniano o DBMS, którego używasz, LIMIT 1 należy zastąpić tym, co DB używa do pobierania pierwszych wyników N.

Będziesz musiał sprawdzić kod w Col1 <= your_value, aby upewnić się, że wartość, której szukasz, znajduje się w zakresie.