Slow Sql Results

Συζητήσεις για τον Microsoft SQL Server

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
papas2
Δημοσιεύσεις: 59
Εγγραφή: 15 Μάιος 2004 18:16

Slow Sql Results

Δημοσίευση από papas2 » 25 Οκτ 2005 16:20

Χρησιμοποιω Visual basic 6 για να φταιχνω προγραμματα συνδεσης με βασεις δεδομενων.Παρατηρησα οτι αν χρησιμοποιησω το ado control για να συνδεθω με εναν sql server 2000, αν οι εγραφες που ζητω να μου επιστραφουν με εναν απλο query p.x.:"Select * from Customers Order By Name" ,ειναι μεχρι καπου 1000 κατι γινεται αλλα αν ειναι π.χ. 300.000 θα πρεπει να ασχοληθω με κατι αλλο για να περασει η ωρα μεχρι να λαβω αποτελεσματα!.Ξερει κανεις τι φταιει?.Me dao control kai access2000 οι εγραφες αυτες κανουν 1-2 sec για να εμφανιστουν.
Πλην του ado control υπαρχει αλλος τροπος να συνδεθω με sql server μεσω της VB που να ειναι ομως γρηγορος?.Τελικα το προβλημα ειναι στον Sql Server ή στη VB6?.Το λεω αυτο γιατι η παραπανω διαδικασια ,μεσω ετοιμων προγραμματων που κυκλοφορουν ,ειναι επισης απελπιστικα αργη.

Άβαταρ μέλους
cordis
Administrator, [F|H]ounder, [C|S]EO
Δημοσιεύσεις: 27622
Εγγραφή: 09 Οκτ 1999 03:00
Τοποθεσία: Greece
Επικοινωνία:

Slow Sql Results

Δημοσίευση από cordis » 25 Οκτ 2005 16:58

για να δεις από που είναι το πρόβλημα μπες στον SQL Server 2000 από τον Query Analyser του ιδίου και κάνε το Select * from Customers Order By Name από εκεί για να δεις χρόνο ανταπόκρισης από ένα εργαλείο που διατίθεται μαζί με τον SQL Server 2000
Δεν απαντάω σε προσωπικά μηνύματα με ερωτήσεις που καλύπτονται από τις ενότητες του forum. Για ο,τι άλλο είμαι εδώ για εσάς.
- follow me @twitter

Άβαταρ μέλους
skeftomilos
Script Master
Δημοσιεύσεις: 2888
Εγγραφή: 07 Ιαν 2005 07:22
Τοποθεσία: Αθήνα

Slow Sql Results

Δημοσίευση από skeftomilos » 26 Οκτ 2005 10:22

Το πρόβλημα είναι καθαρά της VB6. Υποθέτω ότι γεμίζεις με τις εγγραφές του πίνακα ένα Listbox, σωστά; Λοιπόν κάθε φορά που προσθέτεις μία εγγραφή το Listbox ανανεώνει το UI! Καθόλου παράξενο που αργεί τόσο πολύ. Μία λύση είναι να κρύψεις το Listbox πριν το γέμισμα και να το εμφανίσεις αμέσως μετά (ιδιότητα Visible). Πάλι όμως θα καθυστερήσει αρκετά γιατί η VB6 έχει απελπιστικά κακό memory management όσον αφορά Arrays και ιδιαίτερα συλλογές (Collections). Για οτιδήποτε πάνω από 5.000 εγγραφές να είσαι προετοιμασμένος για προβλήματα. Όμως εδώ που τα λέμε το να εμφανίσεις 300.000 εγγραφές ταυτόχρονα στον χρήστη δεν έχει και ιδιαίτερο νόημα. Καλύτερα νομίζω να υλοποιήσεις κάποια λύση με pagination, δηλαδή να βλέπει π.χ. μέχρι 1.000 εγγραφές κάθε φορά. Ή ακόμα καλύτερα να φτιάξεις κατηγορίες αν γίνεται.

Υ.Γ. Η VB.NET δεν έχει τέτοια προβλήματα.
The pure and simple truth is rarely pure and never simple. Ο μη νους δε σκέπτεται μη σκέψεις για το τίποτα.

Άβαταρ μέλους
gcapnias
Δημοσιεύσεις: 14
Εγγραφή: 22 Οκτ 2005 13:53
Τοποθεσία: Σεπόλια, Αθήνα
Επικοινωνία:

Slow Sql Results

Δημοσίευση από gcapnias » 26 Οκτ 2005 18:18

skeftomilos έγραψε:Το πρόβλημα είναι καθαρά της VB6. Υποθέτω ότι γεμίζεις με τις εγγραφές του πίνακα ένα Listbox, σωστά; Λοιπόν κάθε φορά που προσθέτεις μία εγγραφή το Listbox ανανεώνει το UI! Καθόλου παράξενο που αργεί τόσο πολύ. Μία λύση είναι να κρύψεις το Listbox πριν το γέμισμα και να το εμφανίσεις αμέσως μετά (ιδιότητα Visible). Πάλι όμως θα καθυστερήσει αρκετά γιατί η VB6 έχει απελπιστικά κακό memory management όσον αφορά Arrays και ιδιαίτερα συλλογές (Collections). Για οτιδήποτε πάνω από 5.000 εγγραφές να είσαι προετοιμασμένος για προβλήματα. Όμως εδώ που τα λέμε το να εμφανίσεις 300.000 εγγραφές ταυτόχρονα στον χρήστη δεν έχει και ιδιαίτερο νόημα. Καλύτερα νομίζω να υλοποιήσεις κάποια λύση με pagination, δηλαδή να βλέπει π.χ. μέχρι 1.000 εγγραφές κάθε φορά. Ή ακόμα καλύτερα να φτιάξεις κατηγορίες αν γίνεται.

Υ.Γ. Η VB.NET δεν έχει τέτοια προβλήματα.

Η αλήθεια είναι ότι δεν είναι ακριβώς έτσι τα πράγματα... :D

Πρώτα πρώτα αν κάποιος developer υπαινίσεται ότι ο πελάτης του θέλει να δει 10000 εγγραφές μπροστά του κατευθείαν, λέει ψέματα... Το ανθρώπινο μάτι έχει την τάση να πήζει, καλά να δει 100 - 200 εγγραφές... Πόσο μάλλον 10000; Ασε πόση ώρα θα κάνει να κάνει κάποιος να τραβάει το scrollbar να δει την τελευταία εγγραφή...

Στη συνέχεια, 10000 records είναι πολλά δεδομένα, και για τον client που θα τα απεικονίσει, πρέπει να μεταφερθούν 10000 εγγραφές πάνω από το δίκτυο, έστω 1Κ η μία άρα περίπου 10ΜΒ, να φτιαχτούν στο client τα αντικείμενα που θα τα φιλοξενίσουν, περίπου 2 φορές το μέγεθος των data και μετά να κάνει και ένα render ενός control που τα απεικονίσει - άρα θα χρειαστεί εκ των πραγμάτων σημαντική ώρα - και αντίστοιχα από την μεριά του server, που θα πρέπει να σηκώσει πρώτα τα indexes των data, στη συνέχεια τα data από το δίσκο στην μνήμη, και στην συνέχεια θα τα βάλει σε ένα προσωρινό buffer - ακα cursor - για να φύγουν σιγά-σιγά για τον client. Συνεπώς πριν ακόμα φτάσουμε στην υλοποίηση πάλι υπάρχει πρόβλημα...

To ADO Control της VB6 έχει μια ιδιότητα που ονομάζεται CacheSize. Σε αυτή την ιδιότητα ο προγραμματιστής μπορεί να προσδιορίσει τον αριθμό των εγγραφών που θα έρχονται στο local cache του control από την πηγή δεδομένων. Εδώ όμως υπάρχει ένα catch/μυστικό... τα περισσότερα grid control θέλουν να είναι όλα τα δεδομένα στον client για να μπορούν να κάνουν χρήση bookmarks για δική τους χρήση, με αποτέλεσμα να μην χρησιμοποιήται το παραπάνω feature μια και παίζει μόνο όταν ο cursor είναι στο server...

Ακόμη, όλα σχεδόν τα controls της VB6 έχουν την ιδιότητα, Redraw. Αν την κάνεις Redraw=false, πριν κάνεις databind ένα recordset, δεν θα κάνει το ενοχλητικό, όπως είπες, redraw για κάθε γραμμή που μπαίνει στο control. Στο τέλος του databind, μπορείς να κάνεις Redraw=true και να έχεις την τελική μορφή του control σου.

Στην VB.NET και στο .NET Framework γενικότερα, που το μοντέλο διαχείρισης δεδομένων αλλάζει, από το on-line στο off-line, όλα τα δεδομένα μεταφέρονται στον client για να αποθηκευτούν στο dataset. Το dataset δεν είναι τίποτα παραπάνω από μια αναπαράσταση της βάσης στην μνήμη του client. Πιστεύεις, αν ο όγκος των δεδομένων είναι και εκεί 10000 γραμμές δεν θα υποφέρει ο client;

Πιστεύω, ότι αν καταπονείται ή όχι ο client, κατά μεγάλο μέρος φέρει ευθύνη ο προγραμματιστής και όχι το εργαλείο, VB6/.NET/Java κτλ, καθότι είναι υποχρεωμένος να ξέρει τις αδυναμίες του και να τις αποφεύγει, καθώς και να τονίζει τα δυνατά του στοιχεία...


George J.

Άβαταρ μέλους
skeftomilos
Script Master
Δημοσιεύσεις: 2888
Εγγραφή: 07 Ιαν 2005 07:22
Τοποθεσία: Αθήνα

Slow Sql Results

Δημοσίευση από skeftomilos » 26 Οκτ 2005 20:39

ADO Control; Tι μου θύμησες τώρα! Το πρώτο πράγμα που έμαθα σχετικά με το ADO είναι ότι πρέπει να ξεχάσω την ύπαρξη αυτού του control. Ανοίγει αυτόματα μία νέα connection με τη βάση κάθε φορά που ανοίγει η φόρμα. Enough said. :hammer:

Σαφώς και θα υποφέρει ο client αν κατέβουν 300.000 εγγραφές. Η διαφορά είναι ότι με τη VB6 θα υποφέρει 1000 φορές περισσότερο, για λόγους που δε σχετίζονται με αυτό καθαυτό τον όγκο των δεδομένων αλλά με το άθλιο memory management της VBVM. Απ' ό,τι έχω διαπιστώσει το memory allocation για συλλογές έχει τα ίδια χαρακτηριστικά με string concatenation, δηλαδή εκθετική αύξηση του απαιτούμενου χρόνου. Το αστείο είναι ότι το memory deallocation είναι ακόμα πιο άθλιο! Αν μέχρι να φορτώσει η λίστα μπορείς να πας με την ησυχία σου να ψήσεις ένα καφεδάκι, μέχρι να ξεφορτώσει προλαβαίνεις να πεταχτείς μέχρι την Κολομβία για προμήθεια φρέσκου αρωματικού καφέ. :P Συγκριτικά στη VB.NET (και γενικά στο .NET framework) ένα ArrayList με 300.000 στοιχεία χρειάζεται περίπου 1 sec για να γεμίσει, και το ξεφόρτωμα είναι non-blocking καθώς το αναλαμβάνει ο Garbage Collector που τρέχει σε διαφορετικό thread.
The pure and simple truth is rarely pure and never simple. Ο μη νους δε σκέπτεται μη σκέψεις για το τίποτα.

Άβαταρ μέλους
gcapnias
Δημοσιεύσεις: 14
Εγγραφή: 22 Οκτ 2005 13:53
Τοποθεσία: Σεπόλια, Αθήνα
Επικοινωνία:

Slow Sql Results

Δημοσίευση από gcapnias » 26 Οκτ 2005 21:34

skeftomilos έγραψε:ADO Control; Tι μου θύμησες τώρα! Το πρώτο πράγμα που έμαθα σχετικά με το ADO είναι ότι πρέπει να ξεχάσω την ύπαρξη αυτού του control. Ανοίγει αυτόματα μία νέα connection με τη βάση κάθε φορά που ανοίγει η φόρμα.
Τι νομίζεις ότι κάνει το ADO Connection object, στα διαδοχικά Execute ενός SQL string, είτε είναι action είτε όχι;

:P Ανοίγει ένα καινούργιο connection!

Αυτός είναι ένας από τους λόγους που στο ADO.NET σε κάθε connection μπορείς να κάνεις μόνο μια κλήση προς την βάση και μετά να κλείσεις το connection και να το ξανανοίξεις και να κάνεις την επόμενη κλήση!


George J.

Άβαταρ μέλους
skeftomilos
Script Master
Δημοσιεύσεις: 2888
Εγγραφή: 07 Ιαν 2005 07:22
Τοποθεσία: Αθήνα

Slow Sql Results

Δημοσίευση από skeftomilos » 26 Οκτ 2005 22:10

Ok, η Execute είναι ο πιο πρόχειρος τρόπος για εκτέλεση εντολών προς τη βάση αλλά δεν είναι ο μοναδικός. Για τη μέγιστη δυνατή απόκριση μιάς εφαρμογής μπορεί να υπάρχει μονίμως ανοιχτή μία Connection, και για τις εντολές ανάλογα ένα Recordset ή ένα Command ακόμα καλύτερα. Με αυτό τον τρόπο γλιτώνει ο χρήστης από τα 50 msec καθυστέρησης που απαιτεί το άνοιγμα μιάς νέας Connection. :P Φυσικά με αυτό τον τρόπο υπάρχει κίνδυνος εξάντλησης των διαθέσιμων Connections σε ένα multi-user περιβάλλον. :doh:

Για το ADO.NET, που το διάβασες βρε συ ότι δε μπορεί να γίνει δεύτερο query με την ίδια ανοιχτή connection; Όσα να 'ναι μπορούν να γίνουν. Για παράδειγμα όταν υπάρχει ένα DataSet και γίνουν μερικές αλλαγές και μετά γίνει Adapter.Update, θα εκτελεστεί αυτόματα από μία command για κάθε αλλαγμένη DataRow. Ωστόσω στο ADO.NET γίνεται αυτόματο Connection caching, οπότε η διατήρηση μίας ανοιχτής Connection είναι εντελώς ασύμφορη.
The pure and simple truth is rarely pure and never simple. Ο μη νους δε σκέπτεται μη σκέψεις για το τίποτα.

Άβαταρ μέλους
gcapnias
Δημοσιεύσεις: 14
Εγγραφή: 22 Οκτ 2005 13:53
Τοποθεσία: Σεπόλια, Αθήνα
Επικοινωνία:

Slow Sql Results

Δημοσίευση από gcapnias » 27 Οκτ 2005 00:27

skeftomilos έγραψε:Ok, η Execute είναι ο πιο πρόχειρος τρόπος για εκτέλεση εντολών προς τη βάση αλλά δεν είναι ο μοναδικός. Για τη μέγιστη δυνατή απόκριση μιάς εφαρμογής μπορεί να υπάρχει μονίμως ανοιχτή μία Connection, και για τις εντολές ανάλογα ένα Recordset ή ένα Command ακόμα καλύτερα. Με αυτό τον τρόπο γλιτώνει ο χρήστης από τα 50 msec καθυστέρησης που απαιτεί το άνοιγμα μιάς νέας Connection. :P Φυσικά με αυτό τον τρόπο υπάρχει κίνδυνος εξάντλησης των διαθέσιμων Connections σε ένα multi-user περιβάλλον. :doh:
Κάθε προσπέλαση της βάσης δημιουργεί ένα καινούργιο connection στην βάση, αυτόματα, αόρατα. Μάλλον δεν το εξήγησα σωστά, ΟΧΙ object connection, αλλά physical connection επάνω στην βάση! Και όπως λες υπάρχει κινδυνος εξάντλησης των διαθέσιμων connections...
skeftomilos έγραψε:Για το ADO.NET, που το διάβασες βρε συ ότι δε μπορεί να γίνει δεύτερο query με την ίδια ανοιχτή connection; Όσα να 'ναι μπορούν να γίνουν. Για παράδειγμα όταν υπάρχει ένα DataSet και γίνουν μερικές αλλαγές και μετά γίνει Adapter.Update, θα εκτελεστεί αυτόματα από μία command για κάθε αλλαγμένη DataRow. Ωστόσω στο ADO.NET γίνεται αυτόματο Connection caching, οπότε η διατήρηση μίας ανοιχτής Connection είναι εντελώς ασύμφορη.
Δες εδώ SqlCommand.ExecuteReader Method () λέει καθαρά ότι δεν μπορεί να χρησιμοποιηθεί το connection εφόσον υπάρχει ένα reader επάνω στο connection. To δεύτερο, είναι ταυτόχρονο, όχι σειριακό, το ένα μετά το άλλο... To update που αναφέρεις είναι σειριακό και νομίζω ότι αυτό είναι ξεκάθαρο...

Αυτό που λες connection caching, λέγεται connection pooling, και γίνεται και στο ADO. Είναι πιο πολύ feature του provider παρά του ADO/ADO.NET σαν υποσύστημα...


George J.

Άβαταρ μέλους
skeftomilos
Script Master
Δημοσιεύσεις: 2888
Εγγραφή: 07 Ιαν 2005 07:22
Τοποθεσία: Αθήνα

Slow Sql Results

Δημοσίευση από skeftomilos » 27 Οκτ 2005 10:15

George μάλλον συμφωνούμε ... εκτός αν είσαι υπέρμαχος της χρήσης του ADO control οπότε διαφωνούμε! :D
The pure and simple truth is rarely pure and never simple. Ο μη νους δε σκέπτεται μη σκέψεις για το τίποτα.

papas2
Δημοσιεύσεις: 59
Εγγραφή: 15 Μάιος 2004 18:16

Slow Sql Results

Δημοσίευση από papas2 » 03 Νοέμ 2005 04:04

Καταρχας ευχαριστω για το ενδιαφερον και τις απαντησεις.Με ενεπνευσαν ωστε να μπορεσω να λυσω καποια προβληματα αλλα οχι ολα γιατι:

1)Το πραγματικο συστημα που χρησιμοποιω ειναι ενα συστημα διαχειρησης δεδομενων θερμοκρασιων απο διαφορους ανιχνευτες εγκατεστημενους σε καποιες εταιρειες.Αυτη τη στιγμη δουλευω με Access2000 και προγραματα σε VB6 και η κυρια βαση εχει φτασει περιπου 8.500.000 καταχωρησεις.Το συστημα καταγραφει εως 12 records/sec ενω υπαρχουν 4-users.Η ολη βαση δεδομενων ειναι αρκετα απλη κατα τα αλλα.To ολο συστημα εχει ικανοποιιτικη και αποδοτικη λειτουργια.

2)Εξηγαγα 2.500.000 records για δοκιμες σε sql server 2000.Το αρχικο συτημα (πριν την access2000) χρησιμοποιουσε Novell και Btrieve.Πιστευα οτι ο Sql Server θα ηταν εναν συστημα διαχειρησης δεδομενων σαν την Btrieve και οχι μια απλη αποθηκη τους.Αλλα περι αποθηκης προκειται τελικα νομιζω.Για να σηκωσει ολη τη βαση χρειαζεται (σε ολα τα τεστ και σε σταθμο και με τον Query Analizer) περι το 1,5 min, οταν η access θελει περιπου 35 sec και η Btrieve σχεδον 0 sec.Επισης με την access μπορω να καταγραψω ως και 110 records/sec περιπου ενω ο Sql de ξεπερασε τα 40 για λογους που εξηγω και παρακατω.

3)Παρατηρησα
α)οι εντολες της μορφης Select count ειναι επισης 'αργες' 2-4 sec.
β)οταν καποιο ado control κανει π.x. καταγραφες στη βαση σταματα η λειτουργεια ολων των υπολοιπων,η βασικη φορμα του προγραματος εχει περι τα 10 ado controls.Στην access λειτουργουν παραλληλα εστω και με μικρη μειωση της ταχυτητας τους.Αυτο ειναι προβλημα γιατι σε 2 sec το πολυ πρεπει να να ενημερωσω τον κεντρικο μου πινακα αλλα και να λαβω αποτελεσματα απο 6 αλλα ado controls, με select count εντολες.Φυσικα το συστημα δεν προλαβαινει και απρουσιαζονται μεγαλες καθυστερησεις που καθιστουν ανεφαρμοστο πρακτικως.
γ)παρατηρησα οτι ο sql server χρησιμοποιει πολυ περισσοτερο χρονο το δισκο για καταγραφες σε σχεση με την access.Μαλιστα περιοδικα ανα 15 sec περιπου ο δισκος (του server) δουλευει τοσο εντονα που οποιαδηποτε καταγραφη απο πλευρα users σταματα για 2-3 sec.Me την access δεν εχω τετοια προβληματα η αποδοση ειναι παντα ομοιομορφη.
δ)παλαιοτερα ειχα ασχοληθει λιγο με MySql και μου φανηκε γρηγοροτερη και πιο αξιοπιστη αλλα δεν ειμαι σιγουρος σε αυτο.
ε)Μηπως τελικα o Sql Server ειναι ενα ακομη παιχνιδι της Microsoft και προκειται για μια αναβαθμισμενη εκδοση της Access η εγω δεν κανω κατι σωστα?.
στ)Μηπως τελικα πρεπει να ασχοληθω με Pervasive.SQL?.

Άβαταρ μέλους
skeftomilos
Script Master
Δημοσιεύσεις: 2888
Εγγραφή: 07 Ιαν 2005 07:22
Τοποθεσία: Αθήνα

Slow Sql Results

Δημοσίευση από skeftomilos » 04 Νοέμ 2005 01:33

Έχοντας 10 ADO controls σε μία φόρμα σημαίνει ότι υπάρχουν 10 ταυτόχρονες και ανεξάρτητες συνδέσεις με τον Server (φρίκη!). Θα σου πρότεινα να δοκιμάσεις να αντικαταστήσεις τα controls αυτά με κώδικα (Set conn = New ADODB.Connection κ.λπ.). Από αυτή την αλλαγή και μόνο είμαι σίγουρος ότι θα δεις σημαντική διαφορά στην απόδοση. Βέβαια αυτό σημαίνει ότι θα χρειαστεί να προγραμματίσεις και λίγο, όχι μόνο drag-drop και συμπλήρωση ιδιοτήτων! :)

Υπάρχουν ένα σωρό παράγοντες που επηρεάζουν την ταχύτητα όταν δουλεύεις με databases. Πού είναι ο cursor (client ή server); Τι cursor είναι (optimistic ή pessimistic); Τι γίνεται με το locking (shared ή exclusive); Χρησιμοποιείς Recordset ή Commands; Χρησιμοποιείς stored procedures; Τι indexes έχουν οι πίνακες της βάσης; Clustered index; Indexes fragmentation; Σε πόσα φυσικά αρχεία είναι χωρισμένη η βάση;

Δε νομίζω ότι μπορεί να χαρακτηριστεί παιχνίδι ο SQL Server, θα χρειαστεί να μάθεις περισσότερα για να εκμεταλλευτείς τις δυνατότητές του. Το .NET διαθέτει επιπλέον optimization για λειτουργία με τον SQL Server (System.Data.SqlClient.SqlConnection κ.λπ.) που σύμφωνα με τις δοκιμές μου εξασφαλίζει 2x ταχύτητα σε σχέση με κοινή OleDbConnection.
The pure and simple truth is rarely pure and never simple. Ο μη νους δε σκέπτεται μη σκέψεις για το τίποτα.

Απάντηση

Επιστροφή στο “MS SQL Server”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες