2011-01-05 67 views
10

Mà một trong các truy vấn sau sẽ nhanh hơn và nhiều hơn nữa tối ưu (và tại sao):INT vs VARCHAR trong tìm kiếm

  1. SELECT * FROM items WHERE w = 320 AND h = 200 (w và h là INT)

  2. SELECT * FROM items WHERE dimensions = '320x200' (kích thước là VARCHAR)

+2

Tôi sẽ chỉ ra rằng hai cột cũng có khả năng chứa dữ liệu chính xác hơn, điều quan trọng đối với thiết kế cơ sở dữ liệu tốt. – HLGEM

+0

Nó sẽ là một so sánh tốt hơn nếu bạn đã tuyên bố để so sánh chiều cao và chiều rộng như hai varchar riêng biệt. Bạn sẽ nhận được tất cả mọi người trả lời nếu điều này và nếu ... – puck

Trả lời

5

Dưới đây là một số phép đo thực tế. (Sử dụng SQLite; có thể dùng thử với MySQL sau.)

Dữ liệu = Tất cả 1.000.000 kết hợp của w, h ∈ {1 ... 1000}, theo thứ tự ngẫu nhiên.

CREATE TABLE items (id INTEGER PRIMARY KEY, w INTEGER, h INTEGER)

Thời gian trung bình (trong số 20 chạy) để thực hiện SELECT * FROM items WHERE w = 320 and h = 200 là 5,39 ± 0,29 ms.

CREATE TABLE items (id INTEGER PRIMARY KEY, dimensions TEXT)

Thời gian trung bình để thực hiện SELECT * FROM items WHERE dimensions = '320x200' là 5,69 ± 0,23 ms.

Không có sự khác biệt đáng kể, hiệu quả khôn ngoan.

Nhưng

Có sự khác biệt lớn về khả năng sử dụng. Ví dụ, nếu bạn muốn để tính toán diện tích và chu vi của hình chữ nhật, cách tiếp cận hai cột là dễ dàng:

SELECT w * h, 2 * (w + h) FROM items

Cố gắng viết các truy vấn tương ứng cho các cách khác.

+0

'kích thước TEXT' ???? – ajreal

0

trước tiên vì nó nhanh hơn so sánh dữ liệu số.

2

Có lẽ cách duy nhất để biết đó là chạy nó. Tôi sẽ nghi ngờ rằng nếu tất cả các cột được sử dụng được lập chỉ mục, sẽ có cơ bản không có sự khác biệt. Nếu INT là 4 byte, nó sẽ có kích thước gần bằng với chuỗi.

Một nhăn là cách VARCHAR được lưu trữ. Nếu bạn đã sử dụng một kích thước chuỗi không đổi, nó có thể nhanh hơn VARCHAR, nhưng chủ yếu là do bạn cần select *.

Lợi thế lớn của việc sử dụng INT là bạn có thể thực hiện lọc tinh vi hơn nhiều. Điều đó một mình nên là một lý do để thích nó. Điều gì nếu bạn cần một phạm vi, hoặc chỉ chiều rộng, hoặc bạn muốn làm toán trên chiều rộng trong việc lọc? Điều gì về các ràng buộc dựa trên các cột, hoặc tổng hợp?

Ngoài ra, khi bạn nhận được các giá trị vào ngôn ngữ lập trình của mình, bạn sẽ không cần phải phân tích chúng trước khi sử dụng chúng (cần có thời gian).

EDIT: Một số câu trả lời khác đang đề cập đến so sánh chuỗi. Nếu được lập chỉ mục, sẽ không có nhiều chuỗi so sánh được thực hiện. Và có thể thực hiện các thuật toán so sánh rất nhanh mà không cần lặp byte-by-byte. Bạn sẽ phải biết chi tiết về những gì mysql không biết chắc chắn.

1

truy vấn thứ hai, là cơ hội để phù hợp với chuỗi chính xác là nhỏ hơn (có nghĩa là bộ nhỏ hơn các hồ sơ nhưng với cardinality hơn)

truy vấn đầu tiên, rất phù hợp với cột đầu tiên là hàng cao hơn và đang có khả năng phù hợp (ít cardinality)

tất nhiên, giả sử chỉ số được định nghĩa cho cả hai kịch bản

+0

Điều này sẽ không được bù đắp bằng cách tìm kiếm thông qua tập dữ liệu nhỏ hơn, vì truy vấn đầu tiên sẽ chỉ tìm thấy những hàng có trường đầu tiên khớp với nhau, sau đó tìm kiếm trong lĩnh vực thứ hai? – JNK

+0

@JNK - giải thích bản ghi ít hơn nhưng cardinality lớn hơn, so sánh hai cột chỉ ghi nhiều hơn với cardinality thấp hơn trên mỗi cột – ajreal

2

trực giác, nếu bạn không tạo INDEX es trên các cột, số nguyên so sánh có vẻ nhanh hơn.

Trong so sánh số nguyên, bạn so sánh trực tiếp các giá trị 32 bit bình đẳng với các toán tử logic.

Mặt khác, chuỗi là mảng ký tự, sẽ rất khó để so sánh chúng. Character-by-character.

Tuy nhiên, một điểm khác là, trong truy vấn thứ 2 bạn có 1 trường để so sánh, trong truy vấn thứ nhất bạn có 2 trường. Nếu bạn có 1.000.000 hồ sơ và không có chỉ mục trên cột, điều đó có nghĩa là bạn có thể có 1.000.000 so sánh chuỗi trên trường hợp xấu nhất (kết quả không may mắn là điều bạn đang tìm kiếm hoặc không tìm thấy):

Mặt khác bạn có 1.000.000 hồ sơ và tất cả đều là w=320, sau đó bạn sẽ so sánh chúng với số h. Điều đó có nghĩa là 2.000.000 so sánh. Tuy nhiên bạn tạo INDEX trên các trường IMHO chúng sẽ gần như giống nhau vì VARCHAR sẽ được băm (mất O(1) hằng số thời gian) và sẽ được so sánh bằng cách so sánh INT và mất thời gian O(logn).

Kết luận, điều đó tùy thuộc. Ưu tiên chỉ mục trên các cột có thể tìm kiếm và sử dụng ints.

0

Tùy thuộc vào dữ liệu và chỉ mục có sẵn. Nhưng nó là khá có thể cho các phiên bản VARCHAR được nhanh hơn bởi vì tìm kiếm một chỉ số duy nhất có thể được nhanh hơn hai. Nếu kết hợp các giá trị cung cấp một kết quả duy nhất (hoặc "chủ yếu") trong khi mỗi giá trị H/W riêng lẻ có nhiều mục nhập, thì nó có thể thu hẹp xuống thành một tập hợp nhỏ hơn nhiều bằng cách sử dụng chỉ mục duy nhất.

Mặt khác, nếu bạn có chỉ mục nhiều cột trên các cột số nguyên, điều đó có khả năng là hiệu quả nhất.