Mọi tùy chọn liên quan đến thao tác CAST hoặc TRUNCATE hoặc DATEPART trên trường ngày giờ có cùng vấn đề: truy vấn phải quét toàn bộ resultset (40k) để tìm ngày riêng biệt. Hiệu suất có thể thay đổi nhỏ giữa các triển khai khác nhau.
Điều bạn thực sự cần là có chỉ mục có thể tạo phản hồi trong nháy mắt. Bạn có thể có cột được tính liên tục và chỉ mục (yêu cầu thay đổi cấu trúc bảng) hoặc chế độ xem được lập chỉ mục (requires Enterprise Edition for QO to consider the index ngoài hộp).
tồn tính cột:
alter table foo add date_only as convert(char(8), [datetimecolumn], 112) persisted;
create index idx_foo_date_only on foo(date_only);
Indexed xem:
create view v_foo_with_date_only
with schemabinding as
select id
, convert(char(8), [datetimecolumn], 112) as date_only
from dbo.foo;
create unique clustered index idx_v_foo on v_foo_with_date_only(date_only, id);
Cập nhật
Để loại bỏ hoàn toàn một lần quét có thể sử dụng một GROUP BY lừa xem được lập chỉ mục, như thế này:
create view v_foo_with_date_only
with schemabinding as
select
convert(char(8), [d], 112) as date_only
, count_big(*) as [dummy]
from dbo.foo
group by convert(char(8), [d], 112)
create unique clustered index idx_v_foo on v_foo_with_date_only(date_only)
Truy vấn select distinct date_only from foo
sẽ sử dụng chế độ xem được lập chỉ mục này thay thế. Vẫn là một kỹ thuật quét, nhưng trên một chỉ mục đã được phân biệt, vì vậy chỉ các bản ghi cần thiết mới được quét. Đó là một hack, tôi nghĩ, tôi sẽ không khuyên bạn nên nó cho mã sản xuất trực tiếp.
Máy chủ SQL AFAIK không có khả năng quét chỉ mục thực sự với các lần lặp lại, ví dụ: tìm kiếm hàng đầu, sau đó tìm kiếm lớn hơn đầu, sau đó tìm kiếm thành công lớn hơn tìm thấy cuối cùng.
Có cách nào để sử dụng 'QUẢNG CÁO SKIP' trong' SQL Server' không? Tôi vừa thử giải pháp của bạn trên bảng '2M' và thậm chí còn tệ hơn (' DISTINCT CAST (...) 'trên trường' DATETIME' mất '850 ms' với' Hash Match Aggregate', 'DISTINCT date' mất '1800 ms' với' Tập hợp luồng '). 'Oracle' và' MySQL' sẽ chỉ nhảy qua các trường riêng biệt trong chỉ mục, 'SQL Server' không làm điều đó. – Quassnoi
Bạn cần phải chọn date_only riêng biệt sau khi tạo chỉ mục trên đó. –
'@ Remus': Tôi đã tạo chỉ mục và trình tối ưu hóa đã sử dụng nó. – Quassnoi