2010-08-25 45 views
5

Tôi đang phát triển một hệ thống định kỳ (4-5 lần mỗi ngày) chạy một câu lệnh chọn, thường mất ít hơn 10 giây nhưng định kỳ mất tới 40 phút.Truy vấn chậm liên tục trên SQL Server 2008

Cơ sở dữ liệu nằm trên Windows Server 2008 + SQL Server 2008 R2; cả 64bit.

Có một dịch vụ trên máy chạy cơ sở dữ liệu thăm dò ý kiến ​​cơ sở dữ liệu và tạo ra giá trị cho các bản ghi yêu cầu. Những hồ sơ này sau đó được truy vấn định kỳ bằng cách sử dụng một bảng đa tham gia chọn từ một dịch vụ trên một máy thứ hai được viết bằng C++ (VS 2010) bằng cách sử dụng lớp MFC CRecordset để trích xuất dữ liệu. Ví dụ về truy vấn gây ra sự cố được hiển thị bên dưới.

SELECT DISTINCT "JobKeysFrom"."Key" AS "KeyFrom","KeysFrom"."ID" AS "IDFrom", 
"KeysFrom"."X" AS "XFrom","KeysFrom"."Y" AS "YFrom","JobKeysTo"."Key" AS "KeyTo", 
"KeysTo"."ID" AS "IDTo","KeysTo"."X" AS "XTo","KeysTo"."Y" AS "YTo", 
"Matrix"."TimeInSeconds","Matrix"."DistanceInMetres","Matrix"."Calculated" 
FROM "JobKeys" AS "JobKeysFrom" 
INNER JOIN "JobKeys" AS "JobKeysTo" ON 
("JobKeysFrom"."Key"<>"JobKeysTo"."Key") AND 
("JobKeysFrom"."JobID"=531) AND 
("JobKeysTo"."JobID"=531) 
INNER JOIN "Keys" AS "KeysFrom" ON 
("JobKeysFrom"."Key"="KeysFrom"."Key") AND ("JobKeysFrom"."Status"=4) 
INNER JOIN "Keys" AS "KeysTo" ON 
("JobKeysTo"."Key"="KeysTo"."Key") AND ("JobKeysTo"."Status"=4) 
INNER JOIN "Matrix" AS "Matrix" ON 
("Matrix"."IDFrom"="KeysFrom"."ID") AND ("Matrix"."IDTo"="KeysTo"."ID") 
ORDER BY "JobKeysFrom"."Key","JobKeysTo"."Key" 

Tôi đã thử những điều sau

  1. kiểm tra các chỉ mục và tất cả dường như đúng và họ đang hoạt động và đang được sử dụng theo quy định của truy vấn
  2. cố vấn thiết kế trở lại với không gợi ý
  3. Tôi đã cố gắng chống phân mảnh các chỉ mục và dữ liệu
  4. xây dựng lại cơ sở dữ liệu từ đầu bằng cách xuất dữ liệu và nhập lại dữ liệu trong cơ sở dữ liệu mới.
  5. chạy hồ sơ trên đó và thấy rằng khi nó đi sai có vẻ như để làm nhiều triệu (lên đến 100 triệu) của lần đọc chứ không phải là một vài trăm nghìn.
  6. chạy cơ sở dữ liệu trên máy chủ khác nhau

Trong thời gian nó đang chạy truy vấn, tôi có thể chạy chính xác cùng một truy vấn trong cửa sổ quản lý phòng thu và nó sẽ trở lại để chạy trong 10 giây. Vấn đề dường như không bị khóa, bế tắc, CPU, đĩa hoặc bộ nhớ liên quan vì nó đã thực hiện nó khi máy chạy cơ sở dữ liệu chỉ chạy một truy vấn này. Máy chủ có 4 bộ vi xử lý và 16 gb bộ nhớ để chạy nó. Tôi cũng đã thử nâng cấp các đĩa lên nhanh hơn nhiều và điều này không có hiệu lực. Có vẻ như với tôi rằng nó gần như là cơ sở dữ liệu nhận được truy vấn, bắt đầu xử lý nó và sau đó đi ngủ trong 40 phút hoặc chạy truy vấn mà không sử dụng các chỉ mục.

Khi phải mất một thời gian dài nó cuối cùng sẽ kết thúc và gửi kết quả truy vấn (thông thường khoảng 70-100000 bản ghi) trở lại ứng dụng gọi điện.

Bất kỳ trợ giúp hoặc đề xuất nào sẽ được nhận biết ơn, nhiều người cảm ơn

+0

Truy vấn này có chạy như một thủ tục được lưu trữ tham số không? –

+0

Bạn có thể tránh DISTINCT CHỌN không? Điều này có thể làm tổn thương hiệu suất nặng nề. –

+1

@Yves: có vẻ như nó đủ hiệu quả để chạy adhoc và trả về sau 10 giây. –

Trả lời

3

Điều này nghe rất giống với tham số đánh hơi.

Khi thủ tục được lưu trữ được gọi và không có kế hoạch thực hiện hiện tại trong bộ nhớ cache phù hợp với các tùy chọn set cho kết nối, kế hoạch thực hiện mới sẽ được biên dịch bằng cách sử dụng các giá trị tham số truyền vào trong lời gọi đó. Đôi khi điều này sẽ xảy ra khi các thông số được truyền không điển hình (ví dụ như có độ chọn lọc cao bất thường) nên kế hoạch được tạo sẽ không phù hợp với hầu hết các yêu cầu khác với các thông số khác nhau. Ví dụ, nó có thể chọn một kế hoạch với chỉ mục tìm kiếm và đánh dấu tra cứu đó là tốt cho một trường hợp có chọn lọc cao nhưng người nghèo nếu nó cần phải được thực hiện hàng trăm ngàn lần.

Điều này sẽ giải thích tại sao số lần đọc đi qua mái nhà.

kết nối SSMS của bạn có thể sẽ khác nhau SET ... tùy chọn như vậy sẽ không được trao kế hoạch có vấn đề tương tự từ bộ nhớ cache khi bạn thực hiện các thủ tục lưu trữ bên trong SSMS

Bạn có thể sử dụng sau đây để có được kế hoạch cho phiên chậm

select p.query_plan, * 
from sys.dm_exec_requests r 
cross apply sys.dm_exec_query_plan(r.plan_handle) p 
where r.session_id = <session_id> 

Sau đó, so sánh với kế hoạch cho phiên tốt.

Nếu bạn xác định rằng tham số đánh hơi là do lỗi, bạn có thể sử dụng các gợi ý OPTIMIZE FOR để tránh việc chọn gói xấu.

+0

Tôi nghĩ chúng tôi xây dựng các bài giảng về điều kiện và báo cáo ban đầu không hợp lệ :) – garik

0

Kiểm tra xem bạn không có tác vụ bảo trì đang chạy đang xây dựng lại chỉ mục hay thống kê cơ sở dữ liệu của bạn bằng cách nào đó không hợp lệ khi truy vấn được thực hiện. Đây là chính xác loại điều mong đợi để xem truy vấn không sử dụng các chỉ mục của bạn, thường là do các chỉ mục không truy cập được vào truy vấn tại thời điểm nó chạy hoặc vì các số liệu thống kê không hợp lệ và làm cho trình tối ưu hóa tin rằng (các) bảng lớn của bạn chỉ có một vài hàng trong chúng và truy vấn sẽ chạy nhanh hơn với quét toàn bộ bảng hơn là sử dụng truy cập được lập chỉ mục.

+0

Bạn đã bỏ lỡ điểm rằng việc thực hiện đồng thời cùng một truy vấn sẽ trả về nhanh chóng? –

Các vấn đề liên quan