2017-10-02 3 views
2

Oracle 11g. J'ai des tables enfant ML (multilingue) pour le texte, une table enfant par parent/langue. Donc, pour un produit de table parent, j'ai PRODUCT_EN, PRODUCT_FR etc. Je veux avoir une vue unique qui combine toutes les tables ML. Lorsque j'interroge cela pour une langue spécifique, je voudrais qu'Oracle Optimizer (Join Elimination?) Soit suffisamment intelligent pour accéder uniquement à la table ML requise. Donc, si je spécifie lan_id (id de langue) = 5 (français), il devrait ignorer l'anglais et d'autres tables de traduction. est ici quelques vues qui renvoient les données correctes, mais à partir du plan que je vois une requête contre Français encore accéder à l'anglais:Vue Oracle avec tables ML Je souhaite que l'optimiseur utilise une seule table ML

CREATE OR REPLACE VIEW myproduct_ml AS 
SELECT p.PROD_ID, STATUS, 
     ml.lan_id, ml.prod_name 
FROM myproduct p JOIN 
(SELECT en.* FROM myproduct_en en WHERE lan_id = 1 
UNION ALL 
SELECT fr.* FROM myproduct_fr fr WHERE lan_id = 5) ml 
ON (p.prod_id = ml.prod_id); 

CREATE OR REPLACE VIEW myproduct_ml AS 
SELECT p.PROD_ID, STATUS, 
     ml.lan_id, ml.prod_name 
FROM myproduct p JOIN myproduct_en ml ON (p.prod_id = ml.prod_id) WHERE lan_id = 1 
UNION ALL 
SELECT p.PROD_ID, STATUS, 
     ml.lan_id, ml.prod_name 
FROM myproduct p JOIN myproduct_fr ml ON (p.prod_id = ml.prod_id) WHERE lan_id = 5; 

select * from myproduct_ml WHERE lan_id = 5 ; 

lan_id n'a pas besoin d'être dans le tableau ML, comme le suffixe indique le la langue. Pourquoi avez-vous une table distincte pour chaque langue de toute façon?

Répondre

1

Cela voudrait dire d'ajouter une table chaque fois que vous introduisez une nouvelle langue et que vous devez changer toutes les requêtes. Cela ne doit pas être. Les données ajoutées ne doivent entraîner l'ajout que de lignes afin que les requêtes continuent à fonctionner. Donc, faites cette table en une seule langue à la place et vous avez terminé.

+0

J'ai une seule table pour le moment. Mais je conçois pour accélérer le développement. Les tables peuvent être générées de toute façon. Mais ayant une table ML par table/langue parente, je partitionne (je n'ai pas de licence pour l'installation Oracle) les données autant que possible, donc les requêtes accèdent au plus petit ensemble de données. – Duncan

+0

Très mauvaise idée. Cela n'accélère rien. Comme vous le voyez, vous devrez soudainement traiter plusieurs tables dans une requête plutôt qu'une, ce qui ralentit naturellement les choses. Et votre idée que l'optimiseur pourrait voir à travers cela et seulement lire une table ne fonctionne pas. Vous devrez donc écrire toutes vos requêtes de manière dynamique pour éviter cela. Ne fais pas ça. Assurez-vous d'avoir un index approprié sur la clé unique 'prod_id' +' lan_id'. (J'en écrirais même deux, un sur '(prod_id, lan_id)' et un sur (lan_id, prod_id) 'et voir lequel est utilisé.) Cela devrait être assez rapide. –

+0

Merci Thorsten, j'espérais qu'il y avait un moyen de donner à l'optimiseur assez d'indices. Je vais probablement devoir faire avec une table. Mais dans un cas, j'ai plus d'un demi-million de lignes par langue, et je veux supporter 40 langues, donc 20 millions de lignes. Il y a un index de texte sur la colonne ML, et je supporte le chinois, le japonais, le coréen et l'européen, donc je pense à des lexars différents, même si je sais que je peux utiliser MULTI_LEXAR. Je pourrais avoir une table, mais une colonne par langue. Plus d'impact sur l'application, qui doit ajouter _FR au lieu de LAN_ID = 5. – Duncan