SQL Server 2022-ზე ნელი query-ის საპოვნელად დაიწყე Query Store-ით. ის ახალ ბაზებზე ნაგულისხმევად ჩართულია, ყოველი query-ის plan-ებსა და შესრულების სტატისტიკას საათობრივ ინტერვალებად იწერს და restart-ებს გადაურჩება, ამიტომ კითხვას „რა გახდა ნელი გუშინ შუადღეს“ პასუხი აქვს. გახსენი SSMS-ში Top Resource Consuming Queries რეპორტი, დაალაგე ჯამური CPU-ით ან ლოგიკური წაკითხვებით და სიის თავში მდგომი query თითქმის ყოველთვის ის არის, რაც უნდა გამოასწორო. იმისთვის, რაც ნელია ახლა - ამ წამს მიმდინარე request, სესია, რომელიც სხვებს ბლოკავს - ინსტრუმენტი dynamic management view-ებია (sys.dm_exec_requests და მისი მეგობრები). ეს გზამკვლევი ორივეს მოიცავს და იმასაც, რა უნდა უქნა query-ს, როცა იპოვი.
აქ ყველაფერი Express გამოცემაზე მუშაობს. Query Store ყველა გამოცემაშია ხელმისაწვდომი და Express-ზე სხვა ყველგან უფრო მეტად აქვს მნიშვნელობა: ოთხი ბირთვითა და დაახლოებით 1.4 GB buffer pool-ით ერთი ცუდი query მანქანის დიდი ნაწილია.
რას იწერს Query Store#
Query Store ყოველი სამომხმარებლო ბაზის შიგნით ზის და ყოველი query-სთვის, რომლის თვალყურის დევნებასაც გადაწყვეტს, იჭერს:
- query-ის ტექსტს და მის hash-ს, რომ სხვადასხვა სესიიდან მოსული ერთი და იგივე ინსტრუქცია ერთ query-ად ჩაითვალოს.
- ყოველ plan-ს, რომელიც ოპტიმიზატორმა ამ query-სთვის შექმნა, plan-ის XML-ით.
- შესრულების სტატისტიკას თითო plan-ზე, თითო ინტერვალზე: შესრულებები, ხანგრძლივობა, CPU დრო, ლოგიკური და ფიზიკური წაკითხვები, ჩაწერები, memory grant-ები, row-ების რაოდენობა, თითოეული საშუალოდ, მინიმუმად, მაქსიმუმად და სტანდარტულ გადახრად.
- Wait სტატისტიკას თითო plan-ზე, თითო ინტერვალზე (SQL Server 2017-დან), დაჯგუფებულს ისეთ კატეგორიებად, როგორიცაა CPU, Buffer IO, Lock და Memory.
რადგან ის plan-ებს დროის განმავლობაში ინახავს, Query Store პასუხობს კითხვას, რომელსაც plan cache ვერ პასუხობს: „ეს query გასულ კვირას სწრაფი იყო, რა შეიცვალა?“. Plan cache მხოლოდ იმას შეიცავს, რაც ახლაა cache-ში, restart-ზე ყველაფერს კარგავს და მეხსიერების დეფიციტისას ჩანაწერებს აგდებს - რაც Express ინსტანსზე მუდმივად ხდება.
მონაცემები თავად ბაზაში ცხოვრობს. ის backup-ში ბაზასთან ერთად მიდის, აღდგენისას ბრუნდება და - Express-ზე - ითვლება 10 GB-იან ზღვარში თითო ბაზაზე. ეს ბოლო დეტალი განსაზღვრავს, როგორ დააკონფიგურირო ის.
ჩართვა და ზომის შერჩევა#
ჯერ მისი მდგომარეობა შეამოწმე:
SELECT actual_state_desc, desired_state_desc, readonly_reason, current_storage_size_mb, max_storage_size_mb, query_capture_mode_desc, interval_length_minutesFROM sys.database_query_store_options;SQL Server 2022-ზე შექმნილ ბაზებს Query Store read-write რეჟიმში აქვთ ჩართული. ძველი ვერსიებიდან აღდგენილი ან განახლებული ბაზები ინარჩუნებენ იმ პარამეტრს, რაც ჰქონდათ, და ის ხშირად გამორთულია. პატარა სერვერისთვის შესაფერისი პარამეტრებით ჩასართავად:
ALTER DATABASE [appdb] SET QUERY_STORE = ON ( OPERATION_MODE = READ_WRITE, QUERY_CAPTURE_MODE = AUTO, MAX_STORAGE_SIZE_MB = 300, INTERVAL_LENGTH_MINUTES = 60, CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 30), SIZE_BASED_CLEANUP_MODE = AUTO);| პარამეტრი | 2022-ის ნაგულისხმევი | რას აკონტროლებს |
|---|---|---|
OPERATION_MODE | READ_WRITE | READ_ONLY მონაცემებს ინახავს, მაგრამ შეგროვებას წყვეტს |
QUERY_CAPTURE_MODE | AUTO | AUTO ტრივიალურ, იშვიათად გაშვებულ query-ებს ტოვებს; ALL ყველაფერს იჭერს |
MAX_STORAGE_SIZE_MB | 1000 | ადგილი, რომლის გამოყენებაც Query Store-ს ბაზის შიგნით შეუძლია |
INTERVAL_LENGTH_MINUTES | 60 | სტატისტიკის თითოეული ინტერვალის ზომა |
STALE_QUERY_THRESHOLD_DAYS | 30 | რამდენ ხანს ინახება მონაცემები |
SIZE_BASED_CLEANUP_MODE | AUTO | ზომის ზღვართან მიახლოებისას ყველაზე ძველ მონაცემებს შლის |
DATA_FLUSH_INTERVAL_SECONDS | 900 | რამდენად ხშირად იწერება მეხსიერებაში არსებული მონაცემები დისკზე |
10 GB-იან Express ბაზაზე ნაგულისხმევი 1,000 MB-იანი ჭერი შენი ლიმიტის მეათედია. 200-500 MB ტიპური აპლიკაციისთვის ერთი თვის ისტორიას იტევს. Capture რეჟიმი AUTO-ზე დატოვე: ALL აპლიკაციაზე, რომელიც არაპარამეტრიზებულ SQL-ს აგზავნის, store-ს ათასობით ერთჯერადი query-ით ავსებს.
თუ Query Store მაქსიმალურ ზომას მიაღწევს, ის თავს read-only-ზე გადართავს და ჩაწერას წყვეტს, readonly_reason კი გეუბნება, რატომ. ზომაზე დაფუძნებული გაწმენდა ამის თავიდან ასაცილებლადაა; თუ მაინც მოხდა, ლიმიტი ცოტათი გაზარდე ან შენახვის ვადა შეამოკლე, შემდეგ კი ისევ დააყენე OPERATION_MODE = READ_WRITE.
ჩაშენებული რეპორტები#
SSMS-ში გაშალე ბაზა, შემდეგ Query Store. რეპორტები, რომლებიც თავის ადგილს იმსახურებენ:
| რეპორტი | რისთვის გამოიყენო |
|---|---|
| Top Resource Consuming Queries | მთავარი: query-ების რანჟირება ხანგრძლივობით, CPU-ით, წაკითხვებით, მეხსიერებით პერიოდის განმავლობაში |
| Regressed Queries | query-ები, რომელთა წარმადობა გაუარესდა, ჩვეულებრივ plan-ის შეცვლის შემდეგ |
| Queries With High Variation | query-ები, რომლებიც ხან სწრაფია და ხან ნელი - ხშირად parameter sniffing |
| Query Wait Statistics | რას ელოდებიან query-ები, კატეგორიების მიხედვით |
| Overall Resource Consumption | ჯამები დროის განმავლობაში - უფრო დატვირთულია სერვერი, ვიდრე გასულ კვირას? |
| Queries With Forced Plans | ყველაფერი, რაც მიამაგრე, რომ არ დაგავიწყდეს მასთან დაბრუნება |
| Tracked Queries | ერთი query id-ის დროში თვალყურის დევნება |
Top Resource Consuming Queries-ში მეტრიკა ნაგულისხმევიდან შეცვალე ჯამურ CPU დროზე ან ჯამურ ლოგიკურ წაკითხვებზე და არა საშუალოზე. query, რომელიც 4 ms-ს გრძელდება, მაგრამ საათში 2 მილიონჯერ ეშვება, ბევრად მეტი ჯდება, ვიდრე 3-წამიანი რეპორტი, რომელიც დღეში ორჯერ ეშვება, საშუალოები კი ამას მალავს. მარჯვნივ მდებარე დიაგრამა აჩვენებს ყოველ plan-ს, რომელიც არჩეულ query-ს გამოუყენებია, თითო ფერი თითო plan-ზე; query ორი plan-ით, ერთი სწრაფი და ერთი ნელი, plan-ის პრობლემის და არა ინდექსის პრობლემის ყველაზე ნათელი ნიშანია.
ნელი query-ის პოვნა T-SQL-ით#
რეპორტები რამდენიმე catalog view-ზე აგებული ხედებია, რომლებზეც query პირდაპირ შეგიძლია გაუშვა - სასარგებლოა სერვერზე, სადაც მხოლოდ sqlcmd გაქვს, ან შედეგების შესანახად:
SELECT TOP (20) q.query_id, SUM(rs.count_executions) AS executions, SUM(rs.avg_cpu_time * rs.count_executions) / 1000.0 AS total_cpu_ms, SUM(rs.avg_duration * rs.count_executions) / 1000.0 AS total_duration_ms, SUM(rs.avg_logical_io_reads * rs.count_executions) AS total_reads, MAX(qt.query_sql_text) AS query_textFROM sys.query_store_runtime_stats AS rsJOIN sys.query_store_runtime_stats_interval AS i ON i.runtime_stats_interval_id = rs.runtime_stats_interval_idJOIN sys.query_store_plan AS p ON p.plan_id = rs.plan_idJOIN sys.query_store_query AS q ON q.query_id = p.query_idJOIN sys.query_store_query_text AS qt ON qt.query_text_id = q.query_text_idWHERE i.start_time >= DATEADD(HOUR, -24, SYSDATETIMEOFFSET())GROUP BY q.query_idORDER BY total_cpu_ms DESC;Query Store-ში დრო მიკროწამებშია, აქედან 1,000-ზე გაყოფა. შეცვალე ORDER BY total_reads-ზე, რომ იპოვო query-ები, რომლებიც ყველაზე მეტ გვერდს კითხულობენ - მეხსიერებით შეზღუდულ ინსტანსზე სწორედ ისინი აძევებენ ყველაფერს დანარჩენს cache-იდან.
Wait-ები გეუბნებიან, რატომ არის query ნელი, და არა მხოლოდ იმას, რომ ნელია:
SELECT TOP (20) p.query_id, ws.wait_category_desc, SUM(ws.total_query_wait_time_ms) AS wait_msFROM sys.query_store_wait_stats AS wsJOIN sys.query_store_plan AS p ON p.plan_id = ws.plan_idGROUP BY p.query_id, ws.wait_category_descORDER BY wait_ms DESC;CPU wait-ები ნიშნავს, რომ query სამუშაოს აკეთებს - გამოასწორე უკეთესი plan-ით ან ინდექსით. Buffer IO ნიშნავს, რომ ის გვერდებს დისკიდან კითხულობს, რადგან მეხსიერებაში არ იყო. Lock ნიშნავს, რომ მას სხვა სესია ბლოკავს. Memory ნიშნავს, რომ memory grant-ს ელოდება, ხშირად იმიტომ, რომ ცუდმა შეფასებამ ბევრად მეტი მოითხოვა, ვიდრე საჭირო იყო.
რა არის ნელი ახლა: DMV-ები#
Query Store უკან იყურება. პრობლემისთვის, რომელიც ამ წუთში ხდება, ძრავას ჰკითხე, რას აკეთებს:
SELECT r.session_id, r.status, r.command, r.wait_type, r.wait_time, r.blocking_session_id, r.cpu_time, r.logical_reads, r.total_elapsed_time / 1000 AS elapsed_s, t.text AS sql_textFROM sys.dm_exec_requests AS rCROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS tWHERE r.session_id <> @@SPID AND r.session_id > 50ORDER BY r.total_elapsed_time DESC;არანულოვანი blocking_session_id ნიშნავს, რომ request ელოდება lock-ს, რომელსაც ის სესია ფლობს. მიჰყევი ჯაჭვს მის სათავემდე - სესიამდე, რომელიც სხვებს ბლოკავს, მაგრამ თავად დაბლოკილი არ არის - და ნახე, რას უშვებს, ან რა გაუშვა და აღარასოდეს გააკეთა commit. sys.dm_exec_sessions გაძლევს მის login-ს, ჰოსტს და პროგრამის სახელს. პატარა სერვერზე გრძელი ბლოკირების ჯაჭვები ჩვეულებრივ ერთი დავიწყებული ღია ტრანზაქციაა - იგივე დამნაშავე, რომელიც ტრანზაქციების ლოგს truncation-ში უშლის ხელს, და რომელიც განხილულია SQL Server-ის recovery მოდელები და ლოგის ზრდა-ში.
ყველაზე მძიმე query-ებისთვის plan cache-ის ბოლო გასუფთავების შემდეგ sys.dm_exec_query_stats არის Query Store-ის უფრო ძველი ალტერნატივა:
SELECT TOP (10) qs.execution_count, qs.total_worker_time / 1000 AS total_cpu_ms, qs.total_logical_reads, SUBSTRING(t.text, qs.statement_start_offset / 2 + 1, (CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(t.text) ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2 + 1) AS statementFROM sys.dm_exec_query_stats AS qsCROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS tORDER BY qs.total_worker_time DESC;ის მთელ ინსტანსს მოიცავს და მოწყობას არ საჭიროებს, მაგრამ ყველაფერს ივიწყებს restart-ზე და ყოველთვის, როცა plan cache-ს ტოვებს.
Plan-ის რეგრესიები და plan-ის იძულება#
ყველაზე დრამატული შენელებები მონაცემთა ზრდით არ არის გამოწვეული. მათ იწვევს query-ის სხვა plan-ზე გადართვა - სტატისტიკის განახლების, restart-ის, ინდექსის შეცვლის ან compatibility level-ის აწევის შემდეგ. ერთ დღეს query seek-ს აკეთებს; მეორე დღეს scan-ს, კოდში კი არაფერი შეცვლილა.
Query Store ამას ხილულს და გამოსწორებადს ხდის. Regressed Queries-ში ან Tracked Queries-ში plan-ის დიაგრამაზე ძველი plan-ის წერტილები დაბლაა, ახალისა კი მაღლა. აირჩიე კარგი plan და დააჭირე Force Plan-ს, ან გააკეთე ეს T-SQL-ით:
EXEC sp_query_store_force_plan @query_id = 412, @plan_id = 1187;-- Later, once the underlying cause is fixedEXEC sp_query_store_unforce_plan @query_id = 412, @plan_id = 1187;ამის შემდეგ SQL Server ამ query-სთვის ამ plan-ს იყენებს, სანამ ის ვალიდურია. Forcing ლახტია და არა წამალი. ის დღეს სისხლდენას აჩერებს, მაგრამ მონაცემები შეცვლას გააგრძელებს, და plan, რომელიც გასული თვის მონაცემებისთვის სწორი იყო, ექვს თვეში შეიძლება არასწორი იყოს. ჩაინიშნე ყოველი იძულებითი plan, გაარკვიე, რატომ აირჩია ოპტიმიზატორმა ცუდი - მოძველებული სტატისტიკა, დაკარგული ინდექსი, დახრილი პარამეტრი - და მოხსენი იძულება, როცა ეს გამოსწორდება. SQL Server-ს ბოლო კარგი plan-ის ავტომატურად იძულებაც შეუძლია automatic tuning-ის პარამეტრით, სადაც გამოცემა ამას უჭერს მხარს; Express-ზე მასზე დაყრდნობამდე შეამოწმე.
SQL Server 2022-მა დაამატა Query Store hint-ები, რომლებიც query hint-ს query id-ს უმაგრებს აპლიკაციის კოდის შეცვლის გარეშე:
EXEC sys.sp_query_store_set_hints @query_id = 412, @query_hints = N'OPTION (RECOMPILE)';ასე ასწორებ query-ს, რომელსაც ORM აგენერირებს და რომლის რედაქტირებაც ადვილად არ შეგიძლია. sys.sp_query_store_clear_hints მას შლის.
Parameter sniffing და სხვა ჩვეული მიზეზები#
როცა query-ს იპოვი, მიზეზი ჩვეულებრივ მოკლე სიიდან ერთ-ერთია:
- დაკარგული ან უსარგებლო ინდექსი. Plan დიდ ცხრილს scan-ს უკეთებს ან ათასობით key lookup-ს აკეთებს. SQL Server-ის ინდექსები და execution plan-ები მოიცავს plan-ის კითხვასა და ინდექსის დაპროექტებას.
- Parameter sniffing. პარამეტრიზებული query ერთხელ კომპილირდება, პირველი პარამეტრის მნიშვნელობებისთვის, რომლებსაც ხედავს, და ეს plan ყოველი შემდეგი მნიშვნელობისთვის ხელახლა გამოიყენება. თუ პირველი ზარი იყო კლიენტისთვის სამი შეკვეთით, შემდეგი კი სამი მილიონით, ხელახლა გამოყენებული plan შეიძლება საშინელი იყოს. ეს Queries With High Variation-ში ჩანს. გამოსავლები მერყეობს
OPTION (RECOMPILE)-დან იშვიათ query-ზე,OPTIMIZE FOR-მდე წარმომადგენლობით მნიშვნელობაზე და უკეთეს ინდექსამდე, რომელიც ორივეს უხდება. Compatibility level 160-ზე SQL Server 2022-ის parameter sensitive plan ოპტიმიზაციას ზოგიერთი შესაბამისი query-სთვის რამდენიმე plan-ის შენახვა შეუძლია, რაც გეხმარება, მაგრამ ყველა შემთხვევას ვერ იჭერს. - იმპლიციტური კონვერტაციები. სტრიქონის პარამეტრი, გაგზავნილი როგორც
nvarchar,varcharსვეტის წინააღმდეგ, ამიტომ ამ სვეტის ინდექსი seek-ისთვის ვერ გამოიყენება. Plan-ში ეძებეCONVERT_IMPLICIT. - მოძველებული სტატისტიკა დიდი ჩატვირთვის ან წაშლის შემდეგ.
UPDATE STATISTICS dbo.Orders;და შეადარე. - ზედმეტად ბევრი round trip. გვერდი, რომელიც ერთსა და იმავე პატარა query-ს ციკლში 400-ჯერ უშვებს. თითოეული სწრაფია; ჯამი - არა. ჯამური CPU-ის რანჟირება ამათ იჭერს და გამოსავალი აპლიკაციაშია და არა ბაზაში. ზოგადი მეთოდი EXPLAIN ANALYZE და ნელი query-ები-დან აქაც მოქმედებს.
Express-ზე wait-ები გამოცემის ლიმიტებთან მიმართებაშიც წაიკითხე. ბევრი Buffer IO wait ინსტანსზე, სადაც ჯერ კიდევ ბევრი მეხსიერებაა დარჩენილი, ნიშნავს, რომ სამუშაო მონაცემები 1,410 MB-იან buffer pool-ის ჭერს აჭარბებს. გეგმაზე მეტი RAM ამას ვერ შეცვლის; ნაკლები გვერდის წაკითხვა კი შეცვლის, უკეთესი ინდექსებითა და უფრო ვიწრო query-ებით. ბევრი CPU wait ოთხივე დაკავებული ბირთვით გამოთვლითი ჭერია, და იგივე რჩევა მოქმედებს.
მაგალითი: საჩივრიდან გამოსწორებამდე#
საჩივარი ტიპურია: „შეკვეთების გვერდი სამშაბათიდან ნელია“. კოდი არავის შეუცვლია. აი თანმიმდევრობა, რომელიც ამას გამოსწორებად აქცევს, დაახლოებით ოც წუთში.
- დროის ფანჯარა შეავიწროვე. გახსენი Overall Resource Consumption ბოლო კვირისთვის. CPU სამშაბათს დაახლოებით 03:00-ზე ხტება და მაღლა რჩება. იმ მომენტში რაღაც შეიცვალა, 03:00 კი ის დროა, როცა ღამის სტატისტიკის job ეშვება.
- იპოვე query. გახსენი Top Resource Consuming Queries ბოლო 48 საათისთვის, მეტრიკა - ჯამური CPU დრო. ტოპ query, დიდი სხვაობით, შეკვეთების სიაა:
SELECT ... FROM dbo.Orders WHERE CustomerId = @p0 ORDER BY CreatedAt DESC. ის საათში დაახლოებით 30,000-ჯერ ეშვება. - შეხედე მის plan-ებს. დიაგრამა ორ plan-ს აჩვენებს. Plan 1187, რომელიც სამშაბათამდე გამოიყენებოდა, საშუალოდ 2 ms-ია. Plan 1204, რომელიც მას შემდეგ გამოიყენება, საშუალოდ 180 ms-ია. ეს რეგრესიაა და არა ზრდა.
- შეადარე plan-ები. Plan 1187
CustomerId-ზე აგებულ ინდექსზე seek-ს აკეთებს და რამდენიმე key lookup-ს. Plan 1204 clustered ინდექსს scan-ს უკეთებს და ალაგებს. ახალ plan-ზე row-ების შეფასებული რაოდენობა 40,000-ია; რეალური - 12. Plan კომპილირდა სტატისტიკის განახლების შემდეგ, ზარისთვის იმ ერთადერთი საბითუმო კლიენტით, რომელსაც 40,000 შეკვეთა აქვს, და მას შემდეგ ყოველი პატარა კლიენტისთვის ხელახლა გამოიყენება. ეს parameter sniffing-ია, რომელიც სტატისტიკის განახლებით გამოწვეულმა recompile-მა გამოიწვია. - შეაჩერე სისხლდენა. Plan 1187-ს Force გაუკეთე. CPU ერთ წუთში ეცემა და გვერდი ისევ სწრაფია.
- გამოასწორე მიზეზი. ძველი plan-იც მხოლოდ დამაკმაყოფილებელი იყო - მას key lookup-ები სჭირდებოდა. შექმენი ინდექსი
(CustomerId, CreatedAt)-ზე, რომელიც მოიცავს იმ სვეტებს, რომლებსაც გვერდი კითხულობს. covering ინდექსით seek საუკეთესო plan-ია ყოველი კლიენტისთვის, დიდი იქნება თუ პატარა, ამიტომ ოპტიმიზატორს ცუდი არჩევანის გაკეთება აღარ შეუძლია, რა მნიშვნელობაც არ უნდა დაიჭიროს. - მოხსენი იძულება და შეამოწმე. Plan 1187-ს Unforce გაუკეთე. მომდევნო დღის განმავლობაში Tracked Queries-ში ადევნე თვალი query-ს: ჩნდება ახალი plan, რომელიც ახალ ინდექსს იყენებს, საშუალოდ მილიწამზე ნაკლები, და ასე რჩება შემდეგი 03:00-ის სტატისტიკის გაშვების შემდეგაც.
ეს შაბლონი ზოგადდება. Query Store „აპლიკაცია ნელია“-ს ერთ query-მდე და ერთ მომენტამდე ავიწროვებს; plan-ები ხსნის, რა შეიცვალა; forcing დროს გაძლევს; სტრუქტურული გამოსწორება - ინდექსი, გადაწერილი პირობა, გასწორებული პარამეტრის ტიპი - რაიმეს იძულების მიზეზს აქრობს. ერთი ნაბიჯი, რომელსაც ხალხი გამოტოვებს, ბოლოა, და გადაუხედავი იძულებითი plan არის ის, რის გამოც იგივე გვერდი ექვს თვეში ისევ ნელდება, როცა მონაცემები უკვე შეიცვალა და მიმაგრებული plan მას აღარ უხდება.
ეს ასევე აჩვენებს, რატომ არის ჯამური CPU და არა საშუალო ხანგრძლივობა სწორი პირველი რანჟირება. შეკვეთების სია არცერთ „ყველაზე ნელი query-ების“ სიაში არ ჩანდა - 180 ms ერთი ზარისთვის ნელი არ არის - მაგრამ საათში 30,000 ზარით ის სერვერის უდიდესი ნაწილი იყო.
FAQ#
ანელებს Query Store ბაზას?
დამატებითი ხარჯი მცირეა - ტიპურ დატვირთვებზე მაქსიმუმ რამდენიმე პროცენტი, ჩვეულებრივ ნაკლები. მტკივნეული შემთხვევებია capture რეჟიმი ALL არაპარამეტრიზებული query-ების ნიაღვრით, ან ზედმეტად პატარა store, რომელიც დროს გაწმენდაში ატარებს. AUTO capture და გონივრული ზომა ორივეს თავიდან გაცილებს.
ხელმისაწვდომია Query Store SQL Server Express-ზე?
დიახ, ყველა გამოცემაში SQL Server 2016-დან. SQL Server 2022-ზე ის ახალი ბაზებისთვის ნაგულისხმევად ჩართულია. Express-ზე MAX_STORAGE_SIZE_MB ზომიერი დატოვე, რადგან მონაცემები ითვლება 10 GB-იან ზღვარში თითო ბაზაზე.
რატომ არ არის Query Store-ში ის query, რომელიც მაინტერესებს?
Capture რეჟიმით AUTO query-ები, რომლებიც იშვიათად ეშვება და ცოტა ჯდება, არ იჭერება. შეიძლება ის სხვა ბაზაშიც იყოს: Query Store თითო ბაზაზე მუშაობს და query იმ ბაზაში ჩაიწერება, სადაც გაეშვა. შეამოწმე, იყო თუ არა Query Store იმ დროს READ_WRITE რეჟიმში.
როგორ გავასუფთავო Query Store-ის მონაცემები?
ALTER DATABASE [appdb] SET QUERY_STORE CLEAR; შლის ყველაფერს, რაც აქამდე შეგროვდა. ეს სასარგებლოა აპლიკაციის დიდი ცვლილების შემდეგ, როცა ძველი მონაცემები მხოლოდ დააბნევდა რეპორტებს. გაითვალისწინე, რომ ის ასევე აგდებს ისტორიას, რომელიც „მანამდე“ და „მერე“-ს შესადარებლად დაგჭირდებოდა.
უნდა გავუკეთო plan-ებს მუდმივი იძულება?
არა. იძულებითი plan დროებითი გამოსავალია, სანამ ნამდვილ მიზეზს იპოვი. გადახედე იძულებით plan-ებს ყოველი მნიშვნელოვანი მონაცემთა ცვლილების ან განახლების შემდეგ და მოხსენი იძულება, როცა ინდექსის, სტატისტიკის ან query-ის პრობლემა მოგვარდება.




კომენტარები
სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.