2011-01-29 11 views
7

No creo que hay una manera fácil de hacer esto, pero ante la posibilidad de que no hay ...resultados deseados dada y la información de base de datos, programically construir una consulta SQL que da esos resultados

que me dan una cantidad de listas de alrededor de 10000 registros cada una de una tabla de registros de 10 millones. Los datos se generan actualmente mediante consultas en varios elementos no indexados. Quiero generar automáticamente consultas que den los mismos resultados, usando diez campos indexados separados.

¿Existe algún algoritmo conocido para construir algo como esto? Más allá de los conceptos básicos de incluir cada 'nodo' indexado con su propia OR, quiero decir.

Por ejemplo, suponiendo que los datos quería es:

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

y la base de datos original tiene

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

me gustaría algo así como:

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

O tal

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

Pero yo creo prefiero no tengo

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

- a menos que los expertos de bases de datos aquí piensan que eso sería mucho más optimizado en el largo plazo, para el tamaño de la muestra que estamos hablando . El tiempo de ejecución de las consultas es importante; el tiempo de ejecución de la herramienta de conversión no lo es. Tampoco necesito necesariamente obtener la 'mejor' respuesta; 'lo suficientemente bueno' es aceptable.

Mi plan actual es contar, clasificar e iterar buscando cosas que puedan agruparse, para tratar de hacer el menor número posible de "agrupaciones"; Creo que preferiría no tener diez mil (A y B y C y D y E y F y G y H e I y J) en OR juntos.

¿Pensamientos? ¿Asesoramiento experto?

+0

Cualquier idea sobre cómo etiquetar esto, también es apreciada. No es realmente una pregunta SQL, tanto como una pregunta independiente del lenguaje que ocurre en un espacio SQL. Probablemente debería separar la reflexión sobre la optimización en otro lugar; Estoy más interesado en el algoritmo, aquí. – Trevel

+0

Agregué la etiqueta 'algorithm'. Puede haber un algoritmo específico o un problema llamado que se adapte a esto, pero no sé lo que podría ser. –

+0

Todas estas consultas darán como resultado un plan de consulta equivalente en la mayoría de las bases de datos. Los DB no pueden hacer disyunciones de manera eficiente. –

Respuesta

0

Una solución sería utilizar Excepto en los casos que no desee:

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

Otra solución sería simplemente rellenar una tabla temporal con la lista de valores excluidos y utilizar salvo en contra de eso.

adición

La naturaleza del algoritmo utilizado para determinar sus criterios no está claro. ¿Será encontrar elementos para incluir o excluir? Mis dos soluciones iniciales presuponen que está creando una lista de exclusiones. Sin embargo, si está creando una lista de inclusiones, entonces obviamente puede usar Intersecar. Además, es posible que pueda hacer la lista más pequeña usando los valores constructor:

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

Al igual que con la excepción de escenario, es probable que sea más rápido para rellenar una tabla temporal con la combinación que desee y consulta en que se .

1

Lo siento, esta no es realmente una respuesta a su pregunta, sino más bien mis propias reflexiones sobre el problema.

Sugeriría almacenar sus listas en una tabla separada. Eso te permitirá hacer una selección unida de las dos tablas al final. Puede o no usar índices en la tabla de filtros, dependiendo de las pruebas de rendimiento con sus datos.

La implementación exacta diferiría dado el RDMBS particular que intenta utilizar. En mi ejemplo, me quedaré con Oracle, ya que es lo que mejor sé.

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; 

La ventaja de esta solución es que, dado que las estadísticas de la tabla y de índice son completa y fresca, que no tendrá el dolor de cabeza para elegir el orden correcto de los predicados dependiendo de qué y cómo se indexan columnas, en qué orden, cuál es su cardinalidad estimada, etc. El optimizador hará ese trabajo por usted, y debería ser bastante bueno en eso.

0

Esto no es posible sin más restricciones en el problema. Existe un número literalmente infinito de criterios de filtro que puede usar para seleccionar un conjunto de filas de una base de datos, y simplemente no es posible evaluarlas todas. Por ejemplo, supongamos que la vista se construye a partir de filas cuyos ID son primos, o cuyos hashes SHA1 terminan con 0: ¿razonablemente esperaría que algún procedimiento automatizado pudiera descubrir estas reglas?

Además, teniendo en cuenta solo las filas que coinciden, no hay manera de asegurarse de que ninguna regla que genere tampoco seleccionará registros adicionales de la base de datos que no coincidan; el conjunto positivo solo no es suficiente.

+0

Tiene la información de la base de datos. Y no, no esperaría que tome nota de los números primos; el punto es que NO HAY una "Respuesta correcta" disponible a partir de los datos. Es un desastre de datos mayormente aleatorios y quiero encontrar reglas para describirlo en base a los campos indexados. – Trevel

+0

@Trevel Entonces, ¿es aceptable la mayoría de las respuestas correctas? ¿Están los falsos positivos bien? ¿Falsos negativos? ¿Qué debería hacer el sistema si no puede encontrar una solución? –

+0

Los falsos positivos/negativos identificables son aceptables, como dice "no hay una buena respuesta". – Trevel

Cuestiones relacionadas