Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL FIND_IN_SET hoặc tương đương có thể được tạo ra để sử dụng các chỉ số không?

Tham khảo nhận xét của bạn:

@MarcB cơ sở dữ liệu được chuẩn hóa, chuỗi CSV đến từ giao diện người dùng. "Lấy cho tôi dữ liệu cho những người sau:101,202,303"

Câu trả lời này chỉ tập trung vào những con số được phân tách bằng dấu phẩy. Bởi vì, hóa ra, bạn thậm chí còn không nói về FIND_IN_SET sau tất cả.

Có, bạn có thể đạt được những gì bạn muốn. Bạn tạo một câu lệnh đã chuẩn bị sẵn chấp nhận một chuỗi làm tham số như trong Câu trả lời gần đây này của tôi. Trong câu trả lời đó, hãy xem khối thứ hai hiển thị QUY TRÌNH TẠO và tham số thứ 2 của nó chấp nhận một chuỗi như (1,2,3) . Tôi sẽ quay lại vấn đề này trong giây lát.

Không phải bạn cần xem nó @spraff mà những người khác có thể. Nhiệm vụ là lấy loại ! =ALL và could_keys và các khóa của Giải thích để không hiển thị null, như bạn đã hiển thị trong khối thứ hai của mình. Để có cách đọc chung về chủ đề này, hãy xem bài viết Hiểu biết Đầu ra của EXPLAIN và Trang hướng dẫn sử dụng MySQL có tên GIẢI THÍCH Thông tin bổ sung .

Bây giờ, quay lại (1,2,3) tham khảo trên. Chúng tôi biết từ nhận xét của bạn và kết quả Giải thích thứ hai trong câu hỏi của bạn rằng nó đáp ứng các điều kiện mong muốn sau:

  1. type =range (và đặc biệt không phải TẤT CẢ). Xem tài liệu ở trên về điều này.
  2. khóa
  3. không rỗng

Đây chính xác là những điều kiện bạn có trong đầu ra Giải thích thứ hai và đầu ra có thể được nhìn thấy với truy vấn sau:

explain 
select * from ratings where id in (2331425, 430364, 4557546, 2696638, 4510549, 362832, 2382514, 1424071, 4672814, 291859, 1540849, 2128670, 1320803, 218006, 1827619, 3784075, 4037520, 4135373, ... use your imagination ..., ...,  4369522, 3312835);

nơi tôi có 999 giá trị trong in đó danh sách mệnh đề. Đó là mẫu từ câu trả lời này của tôi trong Phụ lục D hơn là tạo một chuỗi csv ngẫu nhiên như vậy, được bao quanh bởi các dấu ngoặc đơn mở và đóng.

Và lưu ý đầu ra Giải thích sau cho phần tử 999 đó trong mệnh đề dưới đây:

Mục tiêu đạt được. Bạn đạt được điều này với một proc được lưu trữ tương tự như proc mà tôi đã đề cập trước đây trong liên kết này sử dụng BÁO CÁO CHUẨN BỊ (và những thứ đó sử dụng concat () theo sau là EXECUTE ).

Chỉ mục được sử dụng, một Tablescan (có nghĩa là xấu) không được trải nghiệm. Các bài đọc khác là Loại tham gia phạm vi , bất kỳ tài liệu tham khảo nào bạn có thể tìm thấy trên MySQL's Cost-Based Optimizer (CBO), câu trả lời này từ vladr mặc dù đã có ngày tháng, theo dõi BẢNG PHÂN TÍCH , cụ thể là sau những thay đổi dữ liệu quan trọng. Lưu ý rằng ANALYZE có thể mất một lượng thời gian đáng kể để chạy trên các tập dữ liệu cực lớn. Đôi khi nhiều giờ.

Các cuộc tấn công Sql Injection:

Việc sử dụng các chuỗi được chuyển đến Thủ tục được lưu trữ là một vectơ tấn công cho các cuộc tấn công SQL Injection. Phải có các biện pháp phòng ngừa để ngăn chặn chúng khi sử dụng dữ liệu do người dùng cung cấp. Nếu quy trình của bạn được áp dụng dựa trên id của chính bạn do hệ thống của bạn tạo ra, thì bạn đã an toàn. Tuy nhiên, lưu ý rằng các cuộc tấn công SQL Injection cấp 2 xảy ra khi dữ liệu được đưa vào đúng vị trí của các quy trình không làm sạch dữ liệu đó trong bản chèn hoặc bản cập nhật trước đó. Các cuộc tấn công được thực hiện trước thông qua dữ liệu và được sử dụng sau (một loại bom hẹn giờ).

Vì vậy, câu trả lời này là Kết thúc phần lớn.

Dưới đây là chế độ xem của cùng một bảng với một sửa đổi nhỏ đối với nó để cho thấy Máy quét bảng đáng sợ sẽ trông giống như trong truy vấn trước (nhưng đối với một cột không được lập chỉ mục có tên là thing ).

Hãy xem định nghĩa bảng hiện tại của chúng tôi:

CREATE TABLE `ratings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `thing` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5046214 DEFAULT CHARSET=utf8;

select min(id), max(id),count(*) as theCount from ratings;
+---------+---------+----------+
| min(id) | max(id) | theCount |
+---------+---------+----------+
|       1 | 5046213 |  4718592 |
+---------+---------+----------+

Lưu ý rằng cột điều trước đây là một cột int nullable.

update ratings set thing=id where id<1000000;
update ratings set thing=id where id>=1000000 and id<2000000;
update ratings set thing=id where id>=2000000 and id<3000000;
update ratings set thing=id where id>=3000000 and id<4000000;
update ratings set thing=id where id>=4000000 and id<5100000;
select count(*) from ratings where thing!=id;
-- 0 rows

ALTER TABLE ratings MODIFY COLUMN thing int not null;

-- current table definition (after above ALTER):
CREATE TABLE `ratings` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `thing` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5046214 DEFAULT CHARSET=utf8;

Và sau đó là Giải thích đó là một Tablescan (đối với cột điều ):




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhận tên bảng bằng cách sử dụng câu lệnh SELECT trong MySQL

  2. Sự kiện Cronjob hoặc MySQL?

  3. Sự khác biệt giữa SQL và MySQL là gì

  4. Hàm MySQL SIN () - Trả về Sine của một số trong MySQL

  5. Ví dụ về MICROSECOND () - MySQL