2009-07-28 30 views

Trả lời

19

Giả sử hiệu suất tối đa là mục tiêu, tôi lý tưởng chọn SUBSTR(my_field,1,6) và tạo chỉ mục dựa trên chức năng để hỗ trợ truy vấn.

CREATE INDEX my_substr_idx 
    ON my_table(substr(my_field,1,6)); 

Khi những người khác chỉ ra, SUBSTR(my_field,1,6) sẽ không thể sử dụng chỉ mục thông thường trên MY_FIELD. Phiên bản LIKE có thể sử dụng chỉ mục, nhưng ước tính cardinality của trình tối ưu hóa trong trường hợp đó thường khá kém nên rất có khả năng không sử dụng chỉ mục khi nó hữu ích hoặc sử dụng chỉ mục khi quét bảng sẽ thích hợp hơn. Lập chỉ mục biểu thức thực tế sẽ cung cấp cho trình tối ưu hóa nhiều thông tin hơn để làm việc với vì vậy, nhiều khả năng chọn chỉ mục chính xác hơn. Một người thông minh hơn tôi có thể đề xuất cách sử dụng thống kê trên các cột ảo trong 11g để cung cấp cho trình tối ưu hóa thông tin tốt hơn cho truy vấn LIKE. Nếu số 6 là biến (tức là đôi khi bạn muốn tìm kiếm 6 ký tự đầu tiên và đôi khi muốn tìm kiếm một số khác), có thể bạn sẽ không thể tìm ra chỉ mục dựa trên chức năng để hỗ trợ truy vấn đó . Trong trường hợp đó, bạn có thể tốt hơn với các thay đổi của các trình tối ưu hóa với công thức LIKE.

9

Trong số hai tùy chọn được cung cấp, chắc chắn LIKE. Phương thức chuỗi con sẽ phải được thực hiện đối với tất cả các hàng trong bảng. Sử dụng LIKE sẽ cho phép sử dụng các chỉ mục.

Để kiểm tra câu trả lời của tôi, chỉ cần lược tả kết quả. Nó sẽ được rõ ràng như ngày.

+0

LIKE là có thể nhanh hơn, không chắc chắn. Ngay cả khi có chỉ mục, nó có thể hoặc không thể được sử dụng tùy thuộc vào tính chọn lọc. –

+0

@Alex - True. Nhưng trong mọi trường hợp, tốt hơn là cố gắng hết sức và cho phép máy chủ tùy chọn sử dụng các chỉ mục nếu có. Sử dụng phương thức chuỗi con đảm bảo rằng không có chỉ mục nào được sử dụng. – beach

+5

Đồng ý. Nhưng bạn có thể tát một chỉ số dựa trên chức năng trên SUBSTR (my_field, 1,6) sẽ có nhiều khả năng được sử dụng hơn chỉ mục thông thường trên my_field cho LIKE. –

2

Nếu bạn có chỉ mục trên my_field, thì LIKE có thể nhanh hơn. Làm tiêu chuẩn của riêng bạn.

0

Tôi sẽ lập hồ sơ cả hai. Nhưng tôi đoán 'LIKE' sẽ nhanh hơn nhiều, bởi vì nó sử dụng tìm kiếm nhị phân trên chỉ mục (nếu trường được lập chỉ mục). Nếu bạn sử dụng phương thức SUBSTR, bạn sẽ kết thúc với việc quét toàn bộ bảng, vì Oracle phải xử lý hàng theo hàng hàm.

1

Có thực sự hai vấn đề ở đây:

  1. Đối với cái nào Oracle sẽ sản xuất cardinality và chi phí ước tính chính xác hơn?
  2. Phương pháp nào linh hoạt hơn về phương pháp truy cập tiềm năng?

Điều này có thể thay đổi theo phiên bản, nhưng cả hai đều khá dễ dàng để thử nghiệm và theo cách đó bạn chắc chắn rằng bạn có thông tin tốt nhất cho phiên bản và dữ liệu của mình.

kế hoạch Run thực hiện cho cả Truy vấn sử dụng ...

explain plan for 
select ... from ... where my_field LIKE 'search%'; 

select * from table(dbms_xplan.display); 

explain plan for 
select ... from ... where substr(my_field,1,6) = 'search'; 

select * from table(dbms_xplan.display); 

Bạn có thể thấy sự khác biệt trong kế hoạch thực hiện, tùy thuộc vào sự hiện diện của chỉ số vv, nhưng cũng so sánh ước tính cardinality với kết quả thực tế mà bạn nhận được từ:

select count(*) from ... where my_field LIKE 'search%'; 

Một trong hai phương pháp có thể chính xác hơn đáng kể so với phương pháp kia.

Nếu không ai trong số họ là chính xác truy vấn này dự kiến ​​sẽ chạy trong một khoảng thời gian không nhỏ, hãy xem xét sử dụng lấy mẫu động để cải thiện ước tính, bởi vì với ước tính cardinality sai, trình tối ưu hóa có thể chọn suboptimal phương pháp truy cập anyway.

explain plan for 
select /*+ dynamic_sampling(4) */ ... from ... where substr(my_field,1,6) = 'search'; 

select * from table(dbms_xplan.display); 

Theo như cách sử dụng chỉ mục, cả hai phương pháp đều có thể sử dụng phương pháp truy cập dựa trên chỉ mục. Vị từ LIKE có thể là chỉ mục thân thiện hơn và có thể sử dụng quét phạm vi hoặc quét chỉ mục đầy đủ nhanh. Phương pháp SUBSTR chắc chắn có thể sử dụng quét chỉ mục đầy đủ nhanh, nhưng liệu trình tối ưu hóa sẽ xem xét việc quét phạm vi được thử nghiệm tốt nhất trên phiên bản của riêng bạn hay không. , n) sẽ không được công nhận là trường hợp đặc biệt, nếu không phải bây giờ thì trong tương lai?

2

Nếu bạn có không có chỉ mục thì không có sự khác biệt. Bởi vì oracle đang thực hiện quét toàn bộ bảng và đánh giá biểu thức cho mỗi hàng. Bạn có thể đặt chỉ mục trên cột để tăng tốc cả hai truy vấn.

CREATE INDEX my_like_idx 
ON my_table(my_field); 

Chỉ mục này linh hoạt hơn và tăng tốc truy vấn bằng cách sử dụng. Nó sẽ làm việc cho bất kỳ so sánh bắt đầu với các ký tự và có giữ chỗ (%) ở cuối. Oracle đang thực hiện quét phạm vi chỉ mục để tìm tất cả các hàng phù hợp.

CREATE INDEX my_substr_idx 
ON my_table(substr(my_field,1,6)); 

Chỉ số này tăng tốc truy vấn bằng chất nền. Nhưng chỉ số này rất đặc biệt để chỉ so sánh 6 ký tự đầu tiên.

Nếu bạn truy vấn một đoạn bắt đầu ở giữa. Việc tạo chỉ mục dựa trên hàm sẽ giúp ích.

WHERE substr(my_field,2,5) = 'earch' 
WHERE my_field like '%earch%' 
+0

http://stackoverflow.com/a/30781872/603516 – Vadzim

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