- vừa được xem lúc

Tăng tốc database index phần 16.2 - Điều kiện ngu (Obfuscated Conditions) với Numeric Strings

0 0 14

Người đăng: Nguyễn Đình Nghĩa

Theo Viblo Asia

Các bạn có thể xem toàn bộ series ở đây

Trong phần này tôi sẽ giới thiệu về nguy hại của việc lưu số bằng kiểu string.

Numeric strings là dữ liệu kiểu số nhưng lại lưu trọng cột kiểu string, mặc dù cách này là một bad practice, nhưng nếu luôn coi nó là string thì nó vẫn có thể sử dụng index.

SELECT ... FROM ... WHERE numeric_string = '42'

Với câu lệnh như trên, cả hai là string nên index có thể sử dụng được trên cột NUMERIC_STRING. Còn nếu bạn không muốn so sánh với chuỗi '42' mà muốn so sánh với số như lệnh sau:

SELECT ... FROM ... WHERE numeric_string = 42

với câu lệnh này, thiếu dấu nháy đơn ( '), strong một số hệ quản trị cơ sở dữ liệu (PostgreSQL) sẽ báo lỗi, tuy nhiên một số hệ quản trị dữ liệu khác sẽ thực hiện chuyển đổi kiểu một cách ngầm định như sau:

SELECT ... FROM ... WHERE TO_NUMBER(numeric_string) = 42

Với chuyển đổi này, rõ ràng thấy hàm xuất hiện bên trái dấu (=), index sẽ không hoạt động ở đây được. Giải pháp của việc này là đẩy hàm sang bên phải dấu bằng (=).

SELECT ... FROM ... WHERE numeric_string = TO_CHAR(42)

Nhưng tại sao Database không convert theo cách này mà lại dùng cách trước? Nguyên nhân là bởi vì convert từ string sang number luôn có một kết quả rõ ràng, còn ngược lại thì chưa chắc. Một số khi được convert về chuỗi có thể chứa dấu cách, có số 0 ở trước, một giá trị số có thể được convert theo nhiều cách.

42
042
0042
00042
...

Bởi vì database không biết format nào được sử dụng trong cột NUMERIC_STRING , nên database convert từ string sang number, cách này có kết quả rõ ràng hơn. Hàm TO_CHAR chỉ trả về một chuỗi ('42') trong câu lệnh trên nên trong trường hợp có nhiều giá trị như trên, chỉ giá trị đầu tiên (42) được tính là đúng, nếu dùng TO_NUMBER, thì giá trị nào cũng đúng. Với hai cách TO_CHAR và TO_NUMBER không những có sai biệt về hiệu năng, mà còn có khác biệt về ngữ nghĩa.

Việc dùng string để lưu number không những ảnh hưởng tới hiệu năng, mà nó còn có thể gây lỗi, bởi vì lỗi gì đó mà nó không thể convert ngược lại sang number có thể là dấu phân cách, dấu trừ v..v. Bởi vậy bạn luôn luôn nên dùng kiểu number để lưu số.

Trong trường hợp bạn lưu số vào cột number mà muốn so sánh số với chuỗi thì sao. Ví dụ câu lệnh dưới dây

SELECT ... FROM ... WHERE numeric_number = '42'

Trong trường hợp này database sẽ convert string sang number , vì vậy sẽ không ảnh hưởng tới việc sử dụng index trên cột 'numeric_number' hiệu năng vẫn đảm bảo. Tuy nhiên nếu bạn convert bằng tay theo cách này

SELECT ... FROM ... WHERE TO_CHAR(numeric_number) = '42'

Thì index sẽ không ăn, và câu lệnh của bạn sẽ chậm đấy.

Chú ý: Có thể bạn không convert câu lệnh như vậy bằng tay, nhưng có thể lệnh của bạn được sinh ra từ framework, ORM hoặc bạn nhét hàm để so sánh trên code rồi tự động sinh ra câu SQL có dạng như trên, sẽ gây ảnh hưởng hiệu năng rất lớn. Vì vậy cần chú ý khi sử dụng hàm trên ORM để tránh trường hợp convert sang câu lệnh chứa điều kiện ngu nhé!

​ Mình có lập group Standard Dev các bạn có thể Join để xây dựng một cộng đồng lập trình viên level quốc tế nhé!

Bình luận

Bài viết tương tự

- vừa được xem lúc

Mô hình quan hệ - thực thể (Entity – Relationship Model)

Mô hình quan hệ thực thể (Entity Relationship model - E-R) được CHEN giới thiệu vào năm 1976 là một mô hình được sử dụng rộng rãi trong các bản thiết kế cơ sở dữ liệu ở mức khái niệm, được xây dựng dựa trên việc nhận thức thế giới thực thông qua tập các đối tượng được gọi là các thực thể và các mối

0 0 132

- vừa được xem lúc

[Embulk #1] Công cụ giúp giảm nỗi đau chuyển đổi dữ liệu

Embulk là gì. Embulk là một công cụ open source có chức năng cơ bản là load các record từ database này và import sang database khác.

0 0 55

- vừa được xem lúc

Window Functions trong MySQL, Nâng cao và cực kì hữu dụng (Phần II).

Chào mọi người, lại là mình đây, ở phần trước mình đã giới thiệu với mọi người về Window Functions Phần I. Nếu chưa rõ nó là gì thì mọi người nên đọc lại trước nha, để nắm được định nghĩa và các key words, tránh mắt chữ O mồm chứ A vì phần này mình chủ yếu sẽ thực hành với các Window Functions.

0 0 107

- vừa được xem lúc

Window Functions trong MySQL, Nâng cao và cực kì hữu dụng (Phần I).

Chào mọi người, mình mới tìm hiểu đc topic Window Functions cá nhân mình cảm thấy khá là hay và mình đánh giá nó là phần nâng cao. Vì ít người biết nên Window Functions thấy rất ít khi sử dụng, thay vì đó là những câu subquery dài dằng dặc như tin nhắn nhắn cho crush, và người khác đọc hiểu được câu

0 0 923

- vừa được xem lúc

Disable và Enable trigger trong Oracle

Origin post: https://www.tranthanhdeveloper.com/2020/12/disable-va-enable-trigger-trong-oracle.html.

0 0 41

- vừa được xem lúc

Lưu trữ dữ liệu với Data Store

. Data Store là một trong những componet của bộ thư viện Android JetPack, nó là một sự lựa chọn hoàn hảo để thay thế cho SharedPreferences để lưu trữ dữ liệu đơn giản dưới dạng key-value. Chúng ta cùng làm một so sánh nhỏ để thấy sự tối ưu của Data Store với SharedPreferences nhé.

0 0 71