Προς το περιεχόμενο

Σπαζοκεφαλιά SQL select (oracle)


random

Προτεινόμενες αναρτήσεις

Δημοσ.

Εχω ενα πρόβλημα σε SQL, και ψάχνω να βρώ το βέλτιστο query σε ταχύτητα,

γιατι το προφανές εχω διαπιστώσει οτι ειναι πολύ αργό.

Δεν ειναι αργό οταν το εκτελεις 1 φορά, αλλα ο χρόνος γινεται πολυ υπολογισιμος

οταν πρεπει να το εκτελείς χιλιάδες φορές κάθε μέρα.

 

εχουμε εναν πίνακα Ranges 50.000 records, και εναν πινακα Atoms 2-30 εκατομ. records

 

τα κυριότερα πεδία...

>Atoms:
------
atom_id number PRIMARY KEY
xcode   varchar2(10)

Ranges:
----------
range_id   number PRIMARY KEY
xcode_from varchar2(10)
xcode_to   varchar2(10)
xvalue    varchar2(100)

 

 

το atoms.xcode πρεπει να ειναι μεταξύ του ranges.xcode_from και του ranges.xcode_to για να πάρουμε το

αντίστοιχο ranges.xvalue για το κάθε atoms.atom_id

 

Sample data:

>Atoms:
------
atom_id xcode
1	5000000000
2	5500000001
3	5600000001
4	5600099999
5	1000000000
6	1000000000

 

 

Ranges:

----------

>range_id   xcode_from   xcode_to   xvalue
1	1000000000	2000000000	ABC
2	2000500000	3000000000	ACJKLJKLDJSLF
3	40000000AA	500000CCCC	EEEFD
4	5000000000	6000000000	PAPAKI
5	5500000000	5600000000	NIK
6	5600000000	5600000099	ZZZZZZZ
7	7000000000	9999999999	A22FFRREWRERWQ

 

θελω λοιπον ενα query που οταν ζητάω το Xvalue tou Atom 5, θα μου επιστρέψει ABC, απο το Range-id 1,

αφου το "1000000000" ειναι μεταξύ των "1000000000"-"2000000000".

 

To "προφανές" query ειναι (με γνωστό απο προηγούμενα queries/ρουτίνες το xcode "1000000000" του atom #1 ) :

 

 

>SELECT xvalue FROM Ranges WHERE "1000000000" BETWEEN xcode_from AND xcode_to;

 

 

βέβαια οπως βλέπουμε απο τα ranges 4, 5 και 6, υπάρχει επικάλυψη των περιοχών, δηλ,

τa range 5 kai 6, περιέχονται μέσα στο 4, θέλουμε την "εσωτερική περιοχή".

αρα η αντιστοιχες σωστές απαντήσεις ειναι αντίστοιχα... για το:

atom 1 με xcode 5000000000 ειναι range_id 4 (5000000000-6000000000), xvalue PAPAKI

atom 2 με xcode 5500000001 ειναι range_id 5 (5500000000-5600000000), xvalue NIK

atom 3 με xcode 5600000001 ειναι range_id 6 (5600000000-5600000099), xvalue ZZZZZZZ

atom 4 με xcode 5600099999 ειναι range_id 4 (5000000000-6000000000), xvalue PAPAKI

 

αλλα αυτό δεν ειναι πρόβλημα, το query μπορει να επιστρέψει πάνω απο ενα record, και να βρούμε ποιό

ταιριάζει καλύτερα, με procedural code PL/SQL.

 

 

το πρόβλημα μου ειναι το query. με το "WHERE 1000000000 BETWEEN xcode_from AND xcode_to" αργεί πολύ.

και ψάχνω τρόπο να το κανω πιό γρήγορο.

 

η βάση ειναι σε Oracle, αλλα το θέμα ειναι γενικής SQL, εχω προβλημα στη λογική, οχι σε συγκεκριμένα features/code της oracle.

 

 

οι πινακες εχουν Indexes σε ολα τα πεδια που συμμετέχουν στα κριτήρια,

και εχουν γίνει Analyze.

και υπάρχει δυνατότητα να προστεθούν και άλλα πεδία στον Ranges, αν αυτό θα βοηθήσει στην ταχύτερη εύρεση.

αλλα δεν γίνεται να προστεθούν αλλα πεδία στον Atoms.

επισης ο ranges , δεν με πειράζει να αυξηθεί σε records, μεχρι και 100% (απο 50 σε 100 χιλιαδες), αν αυτο θα

βοηθούσε σε ταχύτερη εύρεση, που δεν το βλέπω. Μαλλον να μικρύνει πρέπει.

 

 

δηλ, το προβλημα πιστευω μαλλον ειναι στο σχεδιασμό/λογική, και όχι στον κώδικα (εκτος αν με διαψεύσετε).

 

 

μηπως υπάρχει τρόπος να φτιάξω ενα νέο πεδίο, με καποια φόρμουλα, που να παράγεται απο τα from-to,

και στο οποιο να κανω αναζήτηση με = (equality), αντί με BETWEEN,

και να ειναι και μοναδικό, ωστε να επιστρέφει πάντα 1 record ακομα κι αν υπάρχει επικάλυψη;

 

 

 

ευχαριστώ, αν αντέξατε να το διαβάσετε όλο :)

Δημοσ.

Vasika ta data sou einai static h ananewnontai kathe ligo kai ligaki?

an einai sxedon static tote giati den dokimazeis na ftia3eis ena materialized view twn pio syxnwn query kai na ananewneis ayto kathe mia wra?

 

Poustia einai alla leme twra.

Δημοσ.

Βασικά, αν τα ranges ειναι σταθερά, μπορείς να έχεις μια στήλη στον πίνακα atoms με την τιμή και να την υπολογίζεις με triggers

Δημοσ.

ευχαριστώ

 

 

materialized view δεν γινεται γιατι οι συνδιασμοι ειναι παρα πολλοί, οποτε θα κανει και πολυ χρονο να φτιαχτει και θα εχει άπειρα rows.

 

 

 

Η λύση των triggers, ειναι η πιο ορθολογική, αλλα δεν μπορω να την προτίνω/εφαρμόσω πριν σιγουρευτω οτι δεν υπαρχει αλλη λύση.

υπάρχει εμπόδιο οχι τεχνικό, αλλα αντιλήψεων (άλλων) :)

(σημείωσα οτι προσπαθουμε να μην γινει alter ο πινακας Atoms)

 

 

για να παιξει πρέπει να εχω :

εναν trigger στο insert tou atom να βρει το αρχικό xvalue.

εναν trigger στο update tou atom μηπως αλλαξε το xcode του οποτε πεφτει σε αλλο range (σπανιο, αλλα ειναι δυνατό).

 

 

και ενα trigger στα ranges, αν αλλαξει καποιο range ή καποιο xvalue, να βρώ εκεινη τη στιγμή ολα τα σχετιζομενα atoms Kαι να τα ενημερώσω.

αυτο ειναι ψιλομπέρδεμα...

1.μπορει εκεινη τη στιγμη να υπαχουν κλειδωμενα rows στο Atoms

2.an αλλαξει το xvalue ευκολα τα πραγματα..

αλλα αν αλλαξει το range πρεπει να βρώ ποιά ειναι εντός ΤΩΡΑ, και ποιά

ΗΤΑΝ εντος πρίν, αλλα οχι τώρα, αρα τωρα ανηκουν σε αλλο Range, και κλάφτα...

να κανω παλι full scan ολο το atom? την πέθανα τη βάση.

 

 

οποτε ... ψαχνουμε..ακομα

  • 3 εβδομάδες αργότερα...
Δημοσ.
..η βάση ειναι σε Oracle, αλλα το θέμα ειναι γενικής SQL, εχω προβλημα στη λογική, οχι σε συγκεκριμένα features/code της oracle.

Δεν υπαρχει προσωπικη εμπειρια με Oracle..

Τα xcode_from, xcode_to ειναι varchar, ενω οι τιμες ειναι αριθμητικες ???!!!! (αυτο εχει μεγαλο κοστος, στην αναζητηση)..

 

SELECT xvalue FROM Ranges WHERE TO_NUMBER("1000000000" ) BETWEEN TO_NUMBER(xcode_from) AND TO_NUMBER(xcode_to)

Δημοσ.

thanks, το θεμα εχει λυθεί.

η καθυστερηση ειναι λογω του Between,

βρηκα εναν τροπο να κανει αναζητηση με ΙΣΟΝ, και πετάει, αλλα ειναι πολυ ιστορια να το εξηγήσω τωρα.

ευχαριστώ και πάλι..

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...