If you're seeing this message, it means we're having trouble loading external resources on our website.

თუ ვებფილტრს იყენებთ, დარწმუნდით, რომ *.kastatic.org და *.kasandbox.org დომენები არ არის დაბლოკილი.

ძირითადი მასალა

კურსი: კომპიუტერული პროგრამირება > თემა 3

გაკვეთილი 3: რელაციური მოთხოვნა SQL-ში

უფრო ეფექტური SQL, ბრძანებების დაგეგმვისა და ოპტიმიზაციის შედეგად

ახლა, როცა უკვე ისწავლეთ მონაცემთა არჩევის მრავალი გზა და იწყებთ რამდენიმე ცხრილზე SELECT-ების კეთებას, დროა, ვისაუბროთ თქვენი SQL მოთხოვნების მუშაობის დროის შეფასებაზე - რამდენად სწრაფად სრულდება მათი მუშაობა და შესაძლებელია თუ არა მათი აჩქარება?
SQL არის დეკლარაციული ენა (ინგლ. declarative language) - თითოეული მოთხოვნა აცხადებს იმას, რაც გვინდა, რომ შეასრულოს SQL-ის ძრავამ, მაგრამ არ ამბობს, - როგორ. აღმოჩნდა, რომ მოთხოვნების შესრულების ეფექტურობაზე სწორედ ეს როგორ -- ანუ თავად „გეგმა" -- ახდენს გავლენას, ამიტომ ის ძალიან მნიშვნელოვანია.

რატომ ესაჭიროება გეგმა SQL მოთხოვნებს?

მაგალითად, ვთქვათ, გვაქვს ეს მარტივი მოთხოვნა:
SELECT * FROM books WHERE author = "J K Rowling";
ამ მოთხოვნისათვის არსებობს 2 განსხვავებული გზა, რომლითაც SQL-ს შეუძლია, იპოვოს შედეგები:
  • გააკეთეთ „ცხრილის სრული სკანირება": გადახედეთ ცხრილის ყოველ მწკრივს და დააბრუნეთ შესატყვისი მწკრივები.
  • შექმენით „ინდექსი": შექმენით ავტორის მიერ დალაგებული ცხრილის ასლი, შემდეგ ორობითი ძებნით იპოვეთ მწკრივი, რომელშიც ავტორი არის „J K Rowling", იპოვეთ შესატყვისი ID-ები, შემდეგ გამოიყენეთ ორობითი ძებნა თავდაპირველ ცხრილზე, რომელიც აბრუნებს შესატყვისი ID-ის მქონე მწკრივებს.
რომელია უფრო სწრაფი? გააჩნია მონაცემებს და, აგრეთვე, რამდენად ხშირად გაეშვება მოთხოვნა. თუ ცხრილში მხოლოდ 10 მწკრივია, მაშინ სრულ სკანირებას მხოლოდ 10 მწკრივზე უწევს შეხედვა და პირველი გეგმა კარგად იმუშავებს.
თუ ცხრილში 10 მილიონი მწკრივია, მაშინ ცხრილის სრულ სკანირებას დასჭირდება 10 მილიონ მწკრივზე გადახედვა. ამ შემთხვევაში დალაგებულ ცხრილზე ორობითი ძებნის გამოყენება უფრო სწრაფია - ჩვენ მხოლოდ 23 შეხედვა გვჭირდება 10 მილიონ მწკრივში მნიშვნელობის საპოვნელად. თუმცა, დალაგებული ცხრილის შექმნას დრო დასჭირდება (~230 მილიონი ოპერაცია, გააჩნია ჩვენს ძრავას). თუ ამ მოთხოვნას ბევრჯერ ვახორციელებთ (23-ზე მეტჯერ), ან თუ უკვე გვაქვს დალაგებული ცხრილი, მაშინ მეორე გეგმა უკეთესია.
როგორ ირჩევს SQL-ის ძრავა გეგმას? ეს მნიშვნელოვანი ნაბიჯია, რომელზეც ჯერ არ გვილაპარაკია, რადგან ყურადღებას ვამახვილებდით ჩვენი მოთხოვნების სინტაქსზე და არა — მათ იმპლემენტაციაზე. რაც უფრო ღრმად სწავლობთ SQL-ის გამოყენებას დიდ მონაცემთა ბაზებზე, მით უფრო მეტად მნიშვნელოვანი ხდება დაგეგმვის ნაბიჯი.

SQL მოთხოვნის ცვლილებათა სერიები მისი „სასიცოცხლო ციკლის" განმავლობაში

შეგვიძლია, ვიფიქროთ SQL-ის ძრავაზე, რომელიც გადის ამ ნაბიჯებს ჩვენ მიერ მიცემული თითოეული მოთხოვნისათვის:
გაანალიზება (პარსირება), ოპტიმიზაცია, შემდეგ შესრულება
  1. მოთხოვნის ანალიზატორი ამოწმებს, მოთხოვნა არის თუ არა სინტაქსურად გამართული (მაგალითად, მძიმეები არ არის თავის ადგილზე) და სემანტიკურად გამართული (მაგალითად, მოცემული ცხრილები არსებობს თუ არა), თუ შეცდომები დაფიქსირდა, აბრუნებს მათ. თუ ყველაფერი გამართულია, მაშინ ის გადაიქცევა ალგებრულ გამოსახულებად და გადასცემს მას შემდეგ ნაბიჯს.
  2. მოთხოვნის დამგეგმავი და ოპტიმიზატორი აკეთებს რთულ საფიქრალ სამუშაოს. ის თავდაპირველად აკეთებს მარტივ ოპტიმიზაციებს (გაუმჯობესებებს, რომლებსაც შედეგად ყოველთვის მოსდევს უკეთესი შესრულება, მაგალითად 5*10-ს გადააკეთებს 50-ად). ის შემდეგ განიხილავს სხვადასხვა „მოთხოვნის გეგმას", რომელთაც შეიძლება, ჰქონდეთ სხვადასხვანაირი ოპტიმიზაციები, აფასებს თითოეული მოთხოვნის გეგმის მიერ დახარჯულ რესურსებს (CPU-სა და დროს) განსახილველ ცხრილებში არსებული მწკრივების რაოდენობის მიხედვით, შემდეგ ის ირჩევს ოპტიმალურ გეგმას და გადასცემს მას შემდეგ ნაბიჯს.
  3. მოთხოვნის შემსრულებელი იღებს გეგმას, გარდაქმნის მას მონაცემთა ბაზის ოპერაციებად და გვიბრუნებს შედეგებს, თუკი ასეთები არსებობს.

რა ფუნქციას ასრულებენ ადამიანები?

მოთხოვნათა დაგეგმვა და ოპტიმიზაცია ხდება ყოველ მოთხოვნაზე და შეიძლება, მთელი ცხოვრების განმავლობაში გასცემდეთ SQL-ის მოთხოვნებს და ამას ვერ იაზრებდეთ. მიუხედავად ამისა, როგორც კი დაიწყებთ მონაცემთა უფრო დიდ სიმრავლეებზე მუშაობას, უფრო მეტად დაფიქრდებით თქვენი მოთხოვნების სისწრაფეზე და იმ გზებზე, რომლებითაც თქვენი მოთხოვნების შესრულების გაუმჯობესებაა შესაძლებელი.
ხშირად, განსაკუთრებით კომპლექსური მოთხოვნების შემთხვევებში, არსებობს გზები, რომლებითაც შეგიძლიათ, გააუმჯობესოთ მოთხოვნა, და ამას უწოდებენ „მოთხოვნათა გაუმჯობესებას“ (ინგლ. query tuning).
პირველი ნაბიჯია იმ მოთხოვნების იდენტიფიკაცია, რომელთა მორგებაც გსურთ. ამის გაკეთება შეგიძლიათ მონაცემთა ბაზების იმ გამოძახებებზე დაკვირვებით, რომელთაც ყველაზე დიდი დრო ან რესურსი მიაქვთ, მაგალითად, როგორც ეს SQL-ის აღმრიცხველის შემთხვევაშია. ცუდად შემსრულებელი მოთხოვნის განხორციელებას ზოგჯერ იმდენად დიდი დრო დასჭირდება, რომ ის თქვენს მთელ მონაცემთა ბაზას გააფუჭებს. იმედია, დროულად ამოიცნობთ ცუდად შემსრულებელ მოთხოვნებს.
შემდეგი ნაბიჯი არის იმის გაგება, თუ როგორ ახორციელებს კონკრეტული SQL ძრავა მოთხოვნას. ყველა SQL სისტემას მოჰყვება ძრავისთვის მოთხოვნის გზა. SQLite-ში შეგიძლიათ, გამოიყენოთ EXPLAIN QUERY PLAN ყველა SQL-ის წინ, რათა ნახოთ, რას აკეთებს ის კულისებს მიღმა. თუ ამას გამოიყენებთ, მოემზადეთ EXPLAIN QUERY PLAN-ში ღრმად ჩასასვლელად, რადგან „ახსნა“ არის საკმაოდ დაწვრილებითი და იმპლემენტაციის მიხედვით სპეციფიკური. თუ იყენებთ სხვა SQL ძრავს, შეგიძლიათ, მოძებნოთ „how do I get an execution plan in X“ (ქართ. „როგორ მივიღო განხორციელების გეგმა X-ში“).
ახლა მოდის რთული ნაწილი: განხორციელების ამ გეგმის გასაუმჯობესებლად ხელოვნური ოპტიმიზაცია. ეს, აგრეთვე, არის ის ნაწილი, რომელიც ხშირად დამოკიდებულია იმ SQL-ის ძრავის თავისებურებებზე, რომელსაც იყენებთ და, ასევე, თქვენი საკუთარი მონაცემების თავისებურებებზეც.
მაგალითად, გახსოვთ მოთხოვნა, რომელიც ზემოთ განვიხილეთ? თავიდანვე რომ გვცოდნოდა, რომ დაგვჭირდებოდა ასობით მოთხოვნის გაკეთება, რომელიც WHERE-ს ავტორის სვეტზე შეზღუდავდა, მაშინ შევქმნიდით ინდექსს CREATE INDEX-ის გამოყენებით. შემდეგ SQL-ის ძრავს შეეძლებოდა, ამ ინდექსის გამოყენებით ეფექტურად ეპოვა შესატყვისი მწკრივები. შეგიძლიათ, წაიკითხოთ ეს გზამკვლევი SQLite-ის მოთხოვნის დამგეგმავის შესახებ, რათა გაიგოთ, როდის გვეხმარება ინდექსები.
ხშირად, ინდექსების შექმნა გამეორებად მოთხოვნებს უფრო ეფექტურს ხდის. მაგრამ არსებობს სხვა მრავალი მიდგომაც. SQLite-ის შემთხვევაში, შეგიძლიათ, ცოდნა გაიღრმავოთ მათი მოთხოვნის დამგეგმავის მიმოხილვით და „manual" სექციებიდან ჩანიშვნების გაკეთებით.
მოთხოვნათა ოპტიმიზაციებისა და მოთხოვნათა გაუმჯობესების ყველა სირთულის აქ განხილვა არ შეგვიძლია, ამიტომ გირჩევთ, უფრო ღრმად შეისწავლოთ ეს მაშინ, როცა დაგჭირდებათ.
(აი, SQL მოთხოვნის დამგეგმავების სიღრმისეული ახსნები, რომლებიც საინტერესოა: SQL სერვერის მოთხოვნის ოპტიმიზატორი, Oracle SQL Tuning, MSSQL განხორციელების გეგმის საფუძვლები)

გსურთ, შეუერთდეთ დისკუსიას?

გესმით ინგლისური? დააწკაპუნეთ აქ და გაეცანით განხილვას ხანის აკადემიის ინგლისურენოვან გვერდზე.