Làm cách nào để tối ưu hóa một truy vấn để nó tìm kiếm trên một chỉ mục trước và sau đó là một chỉ mục khác


12

Tôi có hai bộ số đo trái đất từ ​​dữ liệu vệ tinh, mỗi bộ có các trường thời gian (mjd cho ngày julian trung bình) và vị trí địa lý (GeoPoint, spacial) và tôi đang tìm kiếm sự trùng hợp giữa hai bộ sao cho thời gian của chúng khớp với ngưỡng 3 giờ (hoặc 0,125 ngày) và khoảng cách của chúng trong phạm vi 200 km với nhau.

Tôi đã tạo các chỉ mục cho cả các trường mjd trên cả bảng và bảng không gian.

Khi tôi chỉ tham gia vào giới hạn thời gian, cơ sở dữ liệu sẽ tính toán 100.000 trận đấu trong 8 giây và tính khoảng cách cho tất cả 100.000 trận đấu trong thời gian đó. Truy vấn trông như thế này:

select top 100000 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )

Và kế hoạch thực hiện là:

Chỉ ràng buộc mjd

Khi được sắp xếp, 9 trong số các khoảng cách là dưới 200km, do đó, có các trận đấu. Vấn đề là, khi tôi thêm ràng buộc khoảng cách và chạy cái này thay vào đó,

select top 10 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
and h.GeoPoint.STDistance(m.GeoPoint)<200000
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )

nó biến mất trong một thời gian dài. Rõ ràng, trong 8 giây, nó có thể tìm thấy 100.000 trận đấu thời gian, 9 trong số đó dưới 200km, vì vậy trình tối ưu hóa phải thử một thứ gì đó tối ưu. Kế hoạch trông tương tự như trên với một bộ lọc về khoảng cách (tôi đoán).

với hằng số không gian, không có bộ lọc không gian

Tôi có thể buộc sử dụng chỉ số không gian với điều này:

select top 5 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0 
from L2V5.dbo.header h join L2.dbo.MLS_Header m 
on h.GeoPoint.STDistance(m.GeoPoint)<200000
and h.mjd between m.mjd-.125 and m.mjd+.125 
option( table hint ( h, index(ix_MJD), index(ix_GeoPoint) ), table hint( m, index(ix_MJD) ) )

cả hai ràng buộc với cả hai chỉ mục

mà sau đó mất 3 phút để tìm 5 trận đấu.

Làm cách nào để tôi nói với trình tối ưu hóa truy vấn sử dụng chỉ mục MJD tìm kiếm trước, và sau đó là chỉ số không gian thứ hai (hoặc đó là những gì nó đang làm) và có cách nào tôi có thể giúp nó bằng cách cho nó biết có bao nhiêu kết quả khớp không? Nếu nó có thể tính toán 100.000 trận đấu với khoảng cách trong 8 giây có 9 dưới 200km, không nên thêm chỉ số không gian làm cho nó nhanh hơn không chậm hơn?

Cảm ơn cho bất kỳ lời khuyên hoặc ý tưởng khác.

EDIT: Để trả lời câu hỏi kế hoạch trông như thế nào mà không có gợi ý, điều này (và phải mất mãi mãi):

không có gợi ý

Cũng có thể đáng nói là có gần 1 triệu bản ghi trong một bảng và 8 triệu trong bảng khác


Kế hoạch truy vấn của bạn trông như thế nào nếu bạn loại bỏ những gợi ý đó?
Zane

@Zane, tôi đã chỉnh sửa bài đăng và thêm kế hoạch truy vấn không có gợi ý. Nó thay thế các tìm kiếm bằng quét và thời gian là rất nhiều.
dùng261963

Câu trả lời:


6

Vấn đề là nó có thể (và biết các chỉ số không gian, có thể sẽ) cho rằng bộ lọc không gian sẽ được lựa chọn nhiều hơn so với bộ lọc thời gian.

Nhưng nếu bạn có một vài triệu hồ sơ trong vòng 200km, thì nó có thể tồi tệ hơn đáng kể.

Bạn đang yêu cầu nó tìm bản ghi trong phạm vi 200km, trả về dữ liệu theo thứ tự không gian. Tìm các hồ sơ trong đó gần đúng lúc có nghĩa là kiểm tra từng cái.

Hoặc nếu không, bạn đang tìm bản ghi theo thời gian và bạn sẽ nhận được kết quả theo thứ tự thời gian. Sau đó, lọc danh sách này đến bán kính 200km là vấn đề kiểm tra từng cái.

Nếu bạn lọc dữ liệu theo hai phạm vi như thế này, sẽ khó áp dụng bộ lọc thứ hai bằng chỉ mục. Bạn có thể tốt hơn nên bảo nó không sử dụng chỉ số không gian nếu bộ lọc thời gian là chặt chẽ hơn.

Nếu cả hai đều lớn riêng lẻ và chúng chỉ chặt chẽ với nhau, thì bạn có một vấn đề phức tạp hơn, một vấn đề mà mọi người đã cố gắng giải quyết trong một thời gian dài và có thể được giải quyết một cách độc đáo bằng các chỉ mục bao trùm 3D (và hơn thế nữa) không gian. Ngoại trừ SQL Server không có chúng.

Lấy làm tiếc.

Chỉnh sửa: thêm thông tin ...

Đây là một vấn đề tương tự với việc tìm các phạm vi thời gian bao gồm một thời điểm cụ thể. Khi bạn tìm kiếm các bản ghi bắt đầu trước thời điểm đó, thì bạn sẽ có một mớ hỗn độn về thời gian kết thúc - và ngược lại. Nếu bạn tìm kiếm những người trong danh bạ điện thoại có họ bắt đầu bằng F, bạn không thể hy vọng tìm thấy những người có tên đầu tiên bắt đầu bằng R rất dễ dàng. Và một chỉ mục trên tên không giúp được gì cho cùng một lý do. Tìm kiếm những thứ trong chỉ mục tiếp theo thật khó khăn khi chỉ số đầu tiên của bạn không phải là một đẳng thức.

Bây giờ, nếu bạn có thể thay đổi bộ lọc ngày của mình thành bộ lọc bình đẳng (hoặc loạt bộ lọc bình đẳng), thì bạn có thể có cơ hội, ngoại trừ chỉ số không gian là một loại chỉ mục đặc biệt và không thể được sử dụng làm cấp độ thứ hai trong một chỉ số tổng hợp.

Vì vậy, bạn để lại một tình huống khó xử, tôi sợ. :

Chỉnh sửa: Thử:

select top 100000 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
where h.GeoPoint.STDistance(m.GeoPoint)/1000.0 < 200
option( table hint ( h, index(ix_MJD) ) );

Lưu ý rằng tôi đang cố tình phá vỡ tính khả dụng bằng cách chia cho 1000 trước khi so sánh với 200. Tôi muốn công việc này được thực hiện trong Tra cứu khóa.

Nhắc bạn, bạn có thể tránh sự cần thiết phải tra cứu (và gợi ý) bằng cách INCLUDEing GeoPoint và Time trong cả hai chỉ mục ix_MJD. Điều đó chắc chắn sẽ lấy đi một phần sức nóng của kế hoạch truy vấn.


Tôi không biết nếu nó thay đổi bất cứ điều gì, nhưng bộ lọc thời gian được lựa chọn nhiều hơn.
dùng261963

Đồng ý. Vì vậy, có thể chấp nhận để xác định tất cả các hàng khớp với thời gian và sau đó kiểm tra từng vị trí mà không có chỉ mục không?
Rob Farley

... Vì vậy, kế hoạch trông giống như kế hoạch ban đầu của bạn, nhưng có thêm một biến vị ngữ hoặc bộ lọc.
Rob Farley

Đề xuất một số thay đổi với một chỉnh sửa nhanh chóng. Bạn không cần gợi ý về m, chỉ cần h. Mặc dù nếu bạn có thể trao đổi cái nào bạn đang thêm vào 1/8, để đảm bảo bạn sửa đổi cột từ bảng nhỏ hơn và sử dụng các giá trị đó để tìm kiếm trong bảng lớn hơn, điều đó cũng sẽ giúp ích. Nếu h là 8M và m là 1M, hãy để lại vị từ GIỮA và gợi ý cho chỉ h. Nếu nó ngược lại, hãy thay đổi vị ngữ và gợi ý của bạn (nhưng tốt hơn là thay đổi gợi ý là thêm các cột đó vào chỉ mục của bạn).
Rob Farley

Cuối cùng, đưa ra tất cả các gợi ý bảng có vẻ hoạt động tốt nhất, miễn là tôi làm h giữa m và không phải là cách khác. Truy vấn không còn sử dụng các chỉ mục GeoPoint nữa, nhưng dù sao nó cũng không sử dụng chúng một cách hiệu quả. Tôi đã đưa cột GeoPoint vào chỉ mục MJD và điều đó đã giúp ích rất nhiều. select top 10000 h.Time, m.Time, m.GeoPoint.STDistance(h.GeoPoint), h.mjd-m.mjd from L2V5.dbo.header h join L2.dbo.MLS_Header m on m.GeoPoint.STDistance(h.GeoPoint)<200000 and m.mjd between h.mjd-.125 and h.mjd+.125 order by h.mjd
dùng261963
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.