2011-01-29 17 views
7

Nie sądzę, istnieje łatwy sposób to zrobić, ale na off szansa, że ​​nie ma ...Podane pożądanych rezultatów oraz informacje bazy danych, programically budować zapytania SQL, który daje te wyniki

Ja podanych liczba list zawierających około 10 000 rekordów z 10 milionów tabel rekordów. Dane są obecnie generowane przez zapytania dotyczące różnych nieindeksowanych elementów. Chcę automatycznie budować zapytania, które dają takie same wyniki, używając dziesięciu oddzielnych indeksowanych pól.

Czy istnieje znany algorytm do budowania czegoś takiego? Poza tym, że mam na myśli podstawy każdego z indeksowanych "węzłów" z własnym OR.

Eg, przy założeniu, że dane chciała to:

Letter, Number 
A, 1 
A, 2 
B, 1 
C, 2 

i oryginalna baza danych ma

Letter, Number 
A, 1 
A, 2 
A, 3 
B, 1 
C, 1 
C, 2 
D, 1 
D, 3 

Chciałbym coś takiego:

WHERE ((Letter = 'A' OR Letter = 'B') AND (Number = 1 OR Number = 2)) 
OR (Letter = 'C' and Number = 2) 

czy może

WHERE (Letter IN ('A', 'B', 'C') AND Number IN (1, 2) 
AND NOT (Number = 1 AND Letter = 'C')) 

Ale myślę Wolałbym nie mieć

WHERE (Letter = 'A' AND Number = '1') OR 
(Letter = 'A' AND Number = '2') OR 
(Letter = 'B' AND Number = '1') OR 
(Letter = 'C' AND Number = '2') 

- chyba że eksperci bazy danych tutaj myślę, że byłoby dużo bardziej zoptymalizowany w dłuższej perspektywie, dla wielkości próby mówimy o . Czas uruchamiania zapytań jest ważny; czas działania narzędzia do konwersji nie jest. Nie potrzebuję też koniecznie uzyskać "najlepszej" odpowiedzi; "wystarczająco dobre" jest dopuszczalne.

Mój obecny plan polega na liczeniu, sortowaniu i iteracji poprzez poszukiwanie rzeczy, które można pogrupować, aby spróbować zrobić jak najmniej "zgrupowań"; Myślę, że wolałbym nie mieć razem dziesięciu tysięcy (A i B oraz C i D oraz E i F oraz G i H oraz I i J).

Myśli? Porada eksperta?

+0

Wszelkie przemyślenia na temat oznaczania tego również zostały docenione. Nie jest to tak naprawdę pytanie SQL, tak samo jak pytanie o charakterze agnostycznym, które zdarza się w przestrzeni SQL. Prawdopodobnie powinienem oddzielić rozmyślania nad optymalizacją gdzie indziej; Bardziej interesuje mnie algorytm, tutaj. – Trevel

+0

Dodałem tag "algorytm". Może istnieć konkretny, nazwany algorytm lub nazwany problem, który pasuje do tego, ale nie wiem, co to może być. –

+0

Wszystkie te zapytania spowodują równoważny plan zapytania dla większości baz danych. Bloki DB nie mogą efektywnie tworzyć rozłączeń. –

Odpowiedz

0

Jednym rozwiązaniem byłoby wykorzystanie wyjątkiem na scenariuszach nie chcesz:

Select Letter, Number 
From Table 
Except 
    (
    Select 'A', 3 
    Union All 
    Select 'C', 1 
    Union All 
    Select Distinct 'D', Number 
    From Table 
    ) 

Innym rozwiązaniem byłoby po prostu wypełnić tabelę tymczasową z listy wykluczonych wartości i używać wyjątkiem przeciwny.

Dodawanie

Charakter algorytmu stosowanego do określenia kryteriów nie jest jasne. Czy znajdzie przedmioty do uwzględnienia lub wykluczenia? Moje pierwsze dwa rozwiązania zakładają, że tworzysz listę wykluczeń. Jeśli jednak tworzysz listę inkluzji, możesz oczywiście użyć przecięcia. Ponadto, może być w stanie dokonać lista mniejsze za pomocą konstruktora Values:

Select Letter, Number 
From Table 
Intersect 
Select * 
From (Values('A',1) 
    , ('A',2), ('A',3), ('B',1), ('C',2)) 

Jak z wyjątkiem sytuacji, to będzie prawdopodobnie szybciej wypełnić tabelę temp z kombinacji chcesz i kwerendy przeciwko, że .

1

Niestety nie jest to odpowiedź na twoje pytanie, ale moje własne rozważania na temat problemu.

Proponuję przechowywanie twoich list w osobnej tabeli. Umożliwi to dokonanie wspólnego wyboru z dwóch tabel na końcu. Możesz lub nie możesz używać indeksów w tabeli filtrów, w zależności od testów wydajności danych.

Dokładna implementacja różni się w zależności od konkretnego RDMBS, którego zamierzasz używać. W moim przykładzie pozostanę przy Oracle, bo to, co wiem najlepiej.

CREATE TABLE t_filter_lists (
    f_letter varchar2(1), 
    f_number number 
); 

-- Optionally, create an index: 
CREATE INDEX ix_filter_lists 
ON t_filter_lists (
    f_letter, 
    f_number 
); 

INSERT INTO t_filter_lists (f_letter, f_number) VALUES ('A', 1); 
INSERT INTO t_filter_lists (f_letter, f_number) VALUES ('A', 2); 
INSERT INTO t_filter_lists (f_letter, f_number) VALUES ('B', 1); 
INSERT INTO t_filter_lists (f_letter, f_number) VALUES ('C', 2); 
COMMIT; 

-- (Oracle-specific part) gather statistics on the filter table 
EXEC DMBS_STATS.GATHER_TABLE_STATS(... 

-- Run your query 
SELECT * 
FROM t_your_table t 
    INNER JOIN t_filter_lists f 
     ON f.f_letter = t.t_letter 
     AND f.f_number = t.t_number; 

Zaletą tego rozwiązania jest to, że, biorąc pod uwagę, że statystyki tabeli i indeksu są kompletne i świeże, nie będzie miał ból głowy, aby wybrać właściwą kolejność predykatów zależności od której i jak kolumny są indeksowane, w jakiej kolejności, jaka jest ich szacunkowa liczność itd. Optymalizator zrobi to za Ciebie i powinno być w tym całkiem niezłe.

0

Nie jest to możliwe bez większych ograniczeń problemu. Istnieje dosłownie nieskończona liczba kryteriów filtrowania, z których można wybrać zestaw wierszy z bazy danych, a po prostu nie można ich wszystkich ocenić. Na przykład, przypuśćmy, że widok jest skonstruowany z wierszy, których identyfikatory są liczbami głównymi, lub których skróty SHA1 kończą się na 0 - czy można rozsądnie oczekiwać, że zautomatyzowana procedura będzie w stanie wykryć te reguły?

Co więcej, biorąc pod uwagę tylko wiersze, które pasują, nie ma pewności, że dowolna utworzona reguła nie wybierze również dodatkowych rekordów z bazy danych, które nie pasują do siebie - sam zestaw dodatni nie wystarcza.

+0

Masz informacje o bazie danych. I nie, nie oczekiwałbym, że odbierze to w liczbach pierwszych - chodzi o to, że NIE jest dostępna "prawidłowa odpowiedź" z danych. Jest to bałagan głównie losowych danych i chcę znaleźć reguły opisujące je na podstawie indeksowanych pól. – Trevel

+0

@Trevel Czy generowanie w większości prawidłowych odpowiedzi jest dopuszczalne? Czy fałszywe alarmy są w porządku? Fałszywe negatywy? Co powinien zrobić system, jeśli nie może znaleźć rozwiązania? –

+0

Możliwe do zidentyfikowania fałszywe alarmy/negatywy, jak mówi "nie ma dobrej odpowiedzi". – Trevel

Powiązane problemy