go backarticles

Articles of SQLschool.gr Team

Another Example Why you must avoid Implicit Conversions in T-SQL

Antonios Chatzipavlis

Εισαγωγή

Αν και δεν είμαι αρκετά σίγουρος ότι όλοι έχουν καταλάβει ότι θα πρέπει να αποφεύγουν όπως ο διάολος το λιβάνι τα implicit conversions εντούτοις αυτό είναι κάτι γνωστό και πηγή δεινών αν αυτό γίνεται στην T-SQL. Υπάρχουν αρκετά άρθρα που το αναφέρουν αυτό και με αυτό το post θα συμπληρώσω και εγώ ακόμα ένα παράδειγμα με σκοπό μήπως και κάποιοι συνετιστούν και σταματήσουν να το κάνουν.

Αυτό το post αποφάσισα να το γράψω μετά από ένα πραγματικό γεγονός που έγινε σε πραγματικό περιβάλλον εργασίας και το οποίο δημιουργούσε αρκετά προβλήματα.
Για να γίνει κατανοητό αυτό ας έρθουμε να δούμε ένα παράδειγμα και για αυτό το λόγο ας έρθουμε να φτιάξουμε μια βάση με ένα πίνακα που θα παίξει το ρόλο του πειραματόζωου και θα είναι ένας πίνακας πελατών όπου η απόφαση που έχουμε είναι να υπάρχει το ΑΦΜ σαν σημείο αναφοράς για το record άρα και primary key. Σε αυτόν θα βάλουμε 10.000 rows. Όλα αυτά μπορούν να γίνουν με τα παρακάτω script

Το Παράδειγμα

CREATE DATABASE LocalTest;
GO
USE LOCALTEST;
GO
CREATE TABLE Customers
(
    AFM CHAR(9) NOT NULL ,
    CustomerName VARCHAR(250) NOT NULL,
    ContactName VARCHAR(50) NOT NULL
);
GO
ALTER TABLE Customers
ADD CONSTRAINT PK_Customers PRIMARY KEY (AFM);
GO

SET NOCOUNT ON;
DECLARE @I INT=100000000;
WHILE @I < 100010000
BEGIN
    INSERT INTO Customers 
    VALUES 
    (
        CAST(@I AS VARCHAR(9)),
        'Customer :'+ CONVERT(VARCHAR,@I),
        'Contact :'+ CONVERT(VARCHAR,@I)
    );
    SET @I+=1;
END;
GO
SELECT    COUNT(*) 
FROM    Customers;
GO
SELECT    AFM,
        CustomerName,
        ContactName
FROM    Customers;
GO

Ελπίζοντας μέχρι εδώ όλα να είναι κατανοητά θα προχωρήσουμε στο επόμενο μας βήμα με το οποίο θα δείξω πως όλα μπορούν να γίνουν άσχημα ξεκινώντας από το ποιο απλό, το οποίο δεν είναι άλλο από το ζητήσω ένα πελάτη με συγκεκριμένο ΑΦΜ.

Έχω δύο developers ο ένας γράφει αυτό ως εξής

SELECT    AFM,
        CustomerName,
        ContactName
FROM    Customers
WHERE AFM='100000010';
GO

Και ο άλλος όπως παρακάτω

SELECT    AFM,
        CustomerName,
        ContactName
FROM    Customers
WHERE AFM=100000010;

Και οι δύο παίρνουν το ίδιο αποτέλεσμα. Αν όμως δω τα execution plans θα διαπιστώσω ότι το ένα έκανε seek που είναι και το λογικό και αυτό ήθελα να γίνει ενώ στο δεύτερο έκανε scan!!!!!. Ωραίο ε;
Ας δούμε όμως και το κόστος τους; Το  πρώτο έχει 4% και το δεύτερο 96%!!!

image

Η Επεξήγηση


 

Τι όμως έκανε το δεύτερο να έχει άλλη συμπεριφορά στην εκτέλεση με συνέπεια να έχω και  μεγαλύτερο κόστος;
Αν στα εxecution plans έρθουμε στο δεύτερο query περάσουμε το mouse στο Clustered Index Scan θα δούμε εμφανίζεται ένα tooltip όπως στην παρακάτω εικόνα

image

Αυτό μπορούμε να το δούμε και επιλέγοντας το node στο execution plan πατήσουμε F4 και μας εμφανιστεί το Properies window

image

 

Και στις δύο εικόνες θα παρατηρήσουμε ότι στο Pedicate λέει ξεκάθαρα ότι έκανε CONVERT_IMPLICIT(int,[LocalTest].[dbo].[Customers].[AFM],0)=[@1], κάτι το οποίο στο πρώτο δεν γίνεται.

Επίλογος

Όλα αυτά έγιναν διότι ο δεύτερος developer αποφάσισε σκεπτόμενος ότι το ΑΦΜ είναι νούμερο και μπορεί να το γράψει όπως το έγγραψε και ο SQL Server το δέχεται καθώς κάνει implicit conversions. Αναρωτιέμαι αν θα το έκανε κάτι τέτοιο αν έγγραφε σε C# και μη μου πείτε ότι εκεί δεν σου επιτρέπει να κάνεις κάτι τέτοιο, στο επιτρέπει αλλά δεν το κάνεις γιατί σου έχει περάσει με ένεση μέσα στο αίμα σου ότι κάτι τέτοιο είναι κακό.


Antonios Chatzipavlis

Antonios Chatzipavlis

Antonios is a Data Solutions Consultant and Trainer. He has been working in IT since 1988. In his career, he has worked as senior developer, IT Manager, Solutions Architect and IT Consultant. Since 1995 he has been devoted on new technologies and software development tools, mainly by Microsoft, either by training company staff and colleagues or assisting them in design, development and implementation as a consultant or chief developer. He has focused in Databases and Data Science since 1995. He specialized in Microsoft SQL Server since version 6.0 in areas like SQL Server Internals, Database Design and Development, Business Intelligence and in 2010 he has started working with Azure Data Platform, NoSQL databases, Big Data Technologies and Machine Learning. He is an active member of many IT communities in Greece, answering colleagues' questions and writing articles in his web site. He is the owner of SQLschool.gr which is a community portal with a lot of information about Microsoft SQL Server. He has been a Microsoft Certified Trainer (MCT) since 2000. Microsoft honored him as MVP on Data Platform due to his activities in SQL Server since 2010. He holds a large number of Microsoft Certifications and Microsoft SQL Server Certifications since version 6.5.


Relative Articles

Leave your comment

COMMENT

FULL NAME

EMAIL ADDRESS

We use Gravatar

WEB SITE



captcha


 

Newsletter

If you want to receive updates from us subscribe below with your email.
Follow us in
PASS chapter logo

The Official PASS Local Group for Greece

About us Contact us Terms of Use Privacy Sing in Register
sql school greece logo
© 2010-2020 All rights reserved

This site uses cookies for operational and analytics purposes only. By continuing to browse this site, you agree to their use.