2011-11-14 40 views
18

bất cứ ai có thể cung cấp bất kỳ bằng chứng cụ thể về hiệu suất khi so sánhPerformance khác biệt khi so sánh số nguyên và so sánh chuỗi

int = int 

và:

string = string 

trong WHERE điều khoản trong MS-SQL.

Ví dụ

select * 
from Samples 
where SamplesID = 5 

và:

select * 
from Samples 
where Name = 'Shampoo' 

Có sự khác biệt hay là hiệu suất giống nhau không?

+1

Trên một bảng mẫu tôi mong chờ các SamplesId là clustered index. Sự hiện diện và hoặc các loại chỉ số có tác dụng lớn. Đây có phải là câu hỏi thực hay lý thuyết? –

+0

@SteveHenderson thay đổi nhận xét của bạn thành "mong đợi SamplesId làm khóa chính" và tôi đồng ý với bạn 100% :) Cột Id thường chỉ định khóa, có thể hoặc không thể là chỉ mục được nhóm. Tất nhiên, đó chỉ là một giả định ... –

+0

@StuartAinsworth No - Tôi cũng hy vọng nó sẽ là chỉ số nhóm. Với một bảng tra cứu đơn giản (Id và Name, với một số thứ khác), tôi sẽ mong đợi thứ tự vật lý của bảng tra cứu đó bằng Id (khóa chính và chỉ mục nhóm). –

Trả lời

10

Câu hỏi thú vị luôn lấy nó khi đọc số nguyên đó nhanh hơn và chưa bao giờ thực sự thử nghiệm. Tôi lấy 1M Tên và họ ngẫu nhiên từ danh sách Liên hệ từ dữ liệu của tôi thành cơ sở dữ liệu không có chỉ mục hoặc khóa chính chỉ là dữ liệu thô. Không có phép đo nào được thực hiện trên phạm vi dữ liệu của tôi trong một trong các cột chưa được chuẩn hóa để phản ánh thực tế của cơ sở dữ liệu của tôi chứ không phải là một bộ thống kê thuần túy.

select top 100 * from tblScratch where contactsurname = '<TestSurname>' order by NEWID() 
select top 100 * from tblScratch where contacttyperef = 1-22 order by NEWID() 

Newid có thể ngẫu nhiên danh sách dữ liệu mỗi lần. Nhanh chóng chạy điều này cho 20 họ và 20 loại. Truy vấn đã được chạy họ hơn ref sau đó họ. Tìm kiếm số tham chiếu nhanh hơn gần gấp 4 lần và sử dụng khoảng 1/2 nên sách đã đúng trong những năm trước.

String -
SELECT TOP 100 * FROM tblScratch WHERE contactsurname = 'hoare' ORDER BY NEWID()

Duration 430ms 
Reads 902 
CPU 203 

Integer -
SELECT TOP 100 * FROM tblScratch WHERE contacttyperef = 3 ORDER BY NEWID()

Duration 136ms 
Reads 902 
CPU 79 
+0

vì vậy điều này có nghĩa rằng so sánh các số nguyên là ít CPU chuyên sâu do đó nó giải quyết hiệu suất tốt hơn. có bất kỳ tài liệu nào từ Microsoft về cách so sánh thực sự hoạt động không? –

+7

Nó không thực sự là một thử nghiệm tốt (xin lỗi), và có khả năng gây hiểu nhầm bởi vì đặt hàng bởi NewID() giới thiệu một yếu tố hoàn toàn không thực tế - nó tạo ra và đơn đặt hàng các hàng bởi một GUID. Người tối ưu hóa sẽ không nhất thiết phải làm điều này sau khi diễn giải câu lệnh WHERE. Bạn có thể lấy TOP và Order theo NEWID() ra và thử lại không? –

2

Đặt cả hai truy vấn của bạn vào cùng một cửa sổ truy vấn. Ở phía trên cùng (trước một trong các truy vấn này) đặt: THIẾT LẬP THỐNG KÊ IO ON

Khi bạn chạy mã với tùy chọn "Bao gồm thực tế kế hoạch thực hiện" (biểu tượng trên thanh công cụ của bạn trông giống như ba hộp nhỏ , khoảng 7 biểu tượng ở bên phải của nút Thực thi)

Điều này sẽ dẫn đến ba tab trong kết quả của bạn: Kết quả, Thư, Kế hoạch. Tin nhắn và Kế hoạch sẽ hiển thị cho bạn chi phí IO và chi phí Thực thi đầy đủ.

Truy vấn có số lớn hơn có chi phí cao nhất! Phương pháp này sẽ cho phép bạn tự chứng minh xem truy vấn nào có chi phí thấp nhất (hiệu suất cao nhất)

+1

BTW, lý do tôi nói để kiểm tra nó, thay vì cung cấp câu trả lời sách giáo khoa là người tối ưu hóa chạy kế hoạch dựa trên xác suất và tùy thuộc vào kích thước và chỉ mục (như Stuart Ainsworth chỉ ra) là đôi khi nhanh hơn quét toàn bộ bảng (đặc biệt là với SELECT *) hơn là thực hiện tra cứu chỉ mục trước khi nhận dữ liệu, vì vậy trình tối ưu hóa sẽ bỏ qua chỉ mục. Hãy tư vấn sách giáo khoa như là một điểm khởi đầu tốt, nhưng bạn thực sự phải kiểm tra nó, và kiểm tra lại như kích thước bảng và cấu trúc thay đổi –

2

Như Steve đã chỉ ra trong các nhận xét, sự hiện diện và hiến pháp của các chỉ mục sẽ ảnh hưởng rất lớn đến kết quả của bạn; tuy nhiên, vì SQL Server làm việc với các trang để tra cứu dữ liệu và các loại cột hẹp hơn có thể lưu trữ nhiều dữ liệu hơn trên mỗi trang, sử dụng loại thu hẹp có thể hoạt động tốt hơn loại rộng hơn, nơi có nhiều giá trị hơn để xem xét.

Vì vậy, nếu bạn có một bảng nhỏ (vài hàng), có thể không quan trọng; cái bàn lớn? Đặt một chỉ mục trên cột int và nó có thể sẽ thực hiện một cột VARCH được lập chỉ mục.

Tất nhiên, những gì cấu thành bảng lớn hay nhỏ tùy thuộc vào phần cứng của bạn.

+3

Điều này cũng chỉ đúng nếu anh ta có trường varchar dài. vì 'int' là 8 byte, anh ta cần trung bình trên 6 ký tự cho mỗi hàng varchcar cho' int' nhỏ hơn – JNK

+0

Các chi tiết cụ thể thường làm hỏng quy tắc tốt, nhưng bạn không thể trả lời mọi câu hỏi bằng " phụ thuộc ". Tinyints (giá trị số nguyên nhưng không phải là int) là 1 byte, nhỏ hơn bất kỳ cột varchar nào (và tương đương với một char (1)). Quy tắc vẫn áp dụng; loại hẹp hơn, tiềm năng hiệu suất tốt hơn. –

1

So sánh các số nguyên phải nhanh hơn, ở mức rất thấp, nó sẽ kết thúc với hướng dẫn 1 cmp. So sánh chuỗi liên quan đến nhiều hướng dẫn hơn và kết quả là hiệu suất kém hơn.
Tôi cho rằng bạn có hoặc không có chỉ mục trên cả hai trường, các chỉ mục đều có chọn lọc, số lượng bản ghi cũng giống nhau

+0

Tôi hiểu rằng nó phải nhanh hơn nhưng tôi đang cố gắng tìm ra nếu có cách cụ thể để chứng minh rằng nó là? điều này cũng có nghĩa là hệ điều hành khác nhau hoặc thậm chí phần cứng có thể tiếp cận khác nhau khi so sánh chuỗi so sánh số nguyên –

+0

Tôi nghĩ cách duy nhất 100% không thể phủ nhận để chứng minh hoặc bác bỏ nó là xem xét mã nguồn SQLServer xử lý chuỗi và so sánh số. Cá nhân, tôi không thấy cách so sánh các chuỗi không trống (so sánh 2 mảng số) có thể nhanh hơn khi so sánh chỉ 2 số. – a1ex07