2010-02-23 17 views
5

Ok,100k hàng trả lại theo một thứ tự ngẫu nhiên, mà không có một thời gian SQL ra xin vui lòng

Tôi đã làm rất nhiều đọc trên trả về một hàng ngẫu nhiên thiết lập vào năm ngoái, và là giải pháp chúng tôi đưa ra là

ORDER BY newid() 

Điều này là tốt cho < 5k hàng. Nhưng khi chúng ta đang nhận được> 10-20k hàng chúng ta đang nhận được thời gian chờ SQL, Kế hoạch thực hiện cho tôi biết rằng 76% chi phí truy vấn của tôi đến từ dòng này. và loại bỏ dòng này tăng tốc độ theo thứ tự độ lớn khi chúng ta có một lượng lớn hàng.

Người dùng của chúng tôi có yêu cầu thực hiện tối đa 100 nghìn hàng tại một thời điểm như thế này.

Để cung cấp cho bạn thêm một chút chi tiết.

Chúng tôi có một bảng có 2,6 triệu chữ số gồm 4 chữ số và chữ số. Chúng tôi sử dụng một bộ ngẫu nhiên trong số này để đạt được mục nhập vào một địa điểm. Ví dụ, nếu chúng ta có một sự kiện với dung lượng 5000, một bộ ngẫu nhiên 5000 trong số này sẽ được rút ra từ bảng sau đó được cấp cho mỗi khách hàng dưới dạng mã vạch, sau đó ứng dụng quét mã vạch ở cửa có cùng một danh sách 5000. Lý do sử dụng mã gồm 4 chữ số alpha (và không phải là số ngu ngốc dài như GUID) là mọi người dễ dàng viết số đó (hoặc nhắn tin cho bạn bè) và chỉ cần mang và nhập nó theo cách thủ công, vì vậy chúng tôi không muốn số lượng lớn ký tự. Khách hàng yêu thích bit btw cuối cùng.

Có cách nào tốt hơn so với ORDER BY newid() hoặc bạn có cách nhanh hơn để nhận 100 nghìn hàng ngẫu nhiên từ bảng có 2,6 triệu?

Oh, và chúng tôi đang sử dụng MS SQL 2005.

Cảm ơn,

Jo

+0

Một điều thú vị ở đây: http://www.sqlteam.com/article/returning-rows-in-random-order-part-ii-revenge-of-the-randomizer –

Trả lời

3

Nếu bạn muốn tạo mã 4 chữ số ngẫu nhiên, tại sao không chỉ tạo cho họ thay vì cố gắng để kéo chúng ra khỏi cơ sở dữ liệu?

Tạo 100k số duy nhất từ ​​0 đến 1.679,616 (là số mã gồm bốn chữ số duy nhất, bỏ qua trường hợp - 2,6 triệu hàng phải có một số trùng lặp) và chuyển đổi chúng thành mã gồm 4 chữ số.

0

Cũng giống như một vấn đề quan tâm, là những gì thực hiện như thế nào nếu bạn thay thế

ORDER BY newid() 

bởi

ORDER BY CHECKSUM(newid()) 
0

Một ý nghĩ là để phá vỡ quá trình này thành những bước. Thêm một cột trong bảng cho một GUID sau đó làm một tuyên bố cập nhật vào bảng thêm GUIDs. Điều này có thể được thực hiện trước thời hạn nếu cần thiết. Sau đó, bạn có thể chạy truy vấn với một đơn đặt hàng trên cột GUID để nhận kết quả theo cùng một cách.

7

Có một bài viết MSDN có tên "Selecting Rows Randomly from a Large Table" nói về vấn đề chính xác này và hiển thị giải pháp (không sử dụng phân loại mà thay vào đó sử dụng mệnh đề WHERE trên cột được tạo để lọc các hàng).

Lý do truy vấn của bạn chậm là điều khoản ORDER BY khiến toàn bộ bảng được sao chép vào tempdb để sắp xếp.

1

Bạn không phải sắp xếp.

DECLARE @RandomNumber int 
DECLARE @Threshold float 
SELECT @RandomNumber = COUNT(*) FROM customers 
SELECT @Threshold = 50000/@RandomNumber 

SELECT TOP 50000 * FROM customers WHERE rand() > @Threshold ORDER BY newid() 
+0

Bạn vẫn đang phân loại vì bạn có ' ORDER BY newid() 'trong truy vấn của bạn. – adrianbanks

+0

nhưng tôi chỉ sắp xếp 50k chứ không phải toàn bộ bảng. Vấn đề là nếu chúng ta chọn hơn 50k với rand() chúng ta phải thả chúng. Nhưng nếu chúng tôi chỉ lấy TOP mà không phân loại, những người đầu tiên trong danh sách sẽ được đặc quyền. – user76035

0

Bạn đã thử sử dụng% (modulo) trên một cột int đã cho chưa? Bạn không chắc cấu trúc bảng của mình là gì, nhưng bạn có thể làm một việc như sau:

chọn 50000 * hàng đầu từ your_table nơi CAST ((CAST (ASCII (SUBSTRING (venuecode, 1,1)) làm varchar (3)) + CAST (ASCII (SUBSTRING (venuecode, 2,1)) dưới dạng varchar (3)) + CAST (ASCII (SUBSTRING (venuecode, 3,1)) dưới dạng varchar (3)) + CAST (ASCII (SUBSTRING) (venuecode, 4,1)) dưới dạng varchar (3))) như là bigint)% 500000 giữa 0 và 50000

Mã trên sẽ lấy tất cả các địa điểm số alpha của bạn và chuyển đổi chúng thành số nguyên rồi chia toàn bộ bảng thành 500.000 nhóm mà bạn đang dùng 50000 trên cùng nằm trong khoảng từ 0 đến 50000. Bạn có thể p nằm với số sau% kể từ (500.000) và bạn có thể chơi với giữa. Điều này nên ngẫu nhiên nó cho bạn. Không chắc chắn nếu mệnh đề where sẽ cắn bạn về hiệu suất, nhưng nó có giá trị một shot. Ngoài ra, không có đơn đặt hàng, không có sự đảm bảo về thứ tự (nếu bạn có nhiều cpus và luồng).

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