tôi có 10 bảng có cùng cấu trúc ngoại trừ tên bảng.thủ tục lưu trữ mysql chậm hơn 20 lần so với truy vấn chuẩn
tôi có một sp (stored procedure) được xác định như sau:
select * from table1 where (@param1 IS NULL OR [email protected])
UNION ALL
select * from table2 where (@param1 IS NULL OR [email protected])
UNION ALL
...
...
UNION ALL
select * from table10 where (@param1 IS NULL OR [email protected])
tôi kêu gọi các sp với dòng sau:
call mySP('test') //it executes in 6,836s
Sau đó, tôi mở một cửa sổ truy vấn tiêu chuẩn mới. Tôi vừa sao chép truy vấn ở trên. Sau đó thay thế @ param1 bằng 'test'.
Điều này được thực hiện bằng 0,321 và nhanh hơn khoảng 20 lần so với quy trình được lưu trữ.
Tôi đã thay đổi giá trị tham số nhiều lần để ngăn kết quả được lưu vào bộ nhớ cache. Nhưng điều này không thay đổi kết quả. SP chậm hơn khoảng 20 lần so với truy vấn chuẩn tương đương.
Bạn có thể giúp tôi tìm hiểu lý do tại sao điều này xảy ra?
Có ai gặp phải sự cố tương tự không?
Tôi đang sử dụng mySQL 5.0.51 trên máy chủ Windows 2008 R2 64 bit.
chỉnh sửa: Tôi đang sử dụng Navicat để kiểm tra.
Bất kỳ ý tưởng nào cũng hữu ích cho tôi.
EDIT1:
Tôi vừa thực hiện một số kiểm tra theo câu trả lời của Barmar.
Tại cuối cùng tôi đã thay đổi các sp như dưới đây với một chỉ một dòng:
SELECT * FROM table1 WHERE [email protected] AND [email protected]
Sau đó, trước tiên tôi thực hiện các truy vấn standart
SELECT * FROM table1 WHERE col1='test' AND col2='test' //Executed in 0.020s
Sau khi tôi gọi là sp của tôi:
CALL MySp('test','test') //Executed in 0.466s
Vì vậy, tôi đã thay đổi hoàn toàn mệnh đề where nhưng không có gì thay đổi. Và tôi gọi là sp từ cửa sổ lệnh mysql thay vì navicat. Nó cho kết quả tương tự. Tôi vẫn còn bị mắc kẹt trên đó.
sp DDL của tôi:
CREATE DEFINER = `myDbName`@`%`
PROCEDURE `MySP` (param1 VARCHAR(100), param2 VARCHAR(100))
BEGIN
SELECT * FROM table1 WHERE col1=param1 AND col2=param2
END
Và col1 và col2 được kết hợp lập chỉ mục.
Bạn có thể nói rằng tại sao bạn không sử dụng truy vấn standart? Thiết kế phần mềm của tôi không thích hợp cho việc này. Tôi phải sử dụng thủ tục lưu trữ. Vì vậy, vấn đề này rất quan trọng đối với tôi.
EDIT2:
Tôi đã nhận được thông tin hồ sơ truy vấn. Sự khác biệt lớn là do "gửi hàng dữ liệu" trong Thông tin Tiểu sử SP. Gửi phần dữ liệu mất 99% thời gian thực hiện truy vấn. Tôi đang làm thử nghiệm trên máy chủ cơ sở dữ liệu địa phương. Tôi không kết nối từ máy tính từ xa.
SP Hồ sơ Informations
Query Hồ sơ Informations
Tôi đã cố gắng tuyên bố lực lượng chỉ số như dưới đây trong sp của tôi. Nhưng cùng một kết quả.
SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE [email protected] AND [email protected]
Tôi đã thay đổi sp như dưới đây.
EXPLAIN SELECT * FROM table1 FORCE INDEX (col1_col2_combined_index) WHERE col1=param1 AND col2=param2
này cho kết quả này:
id:1
select_type=SIMPLE
table:table1
type=ref
possible_keys:NULL
key:NULL
key_len:NULL
ref:NULL
rows:292004
Extra:Using where
Sau đó, tôi đã thực hiện các truy vấn dưới đây.
EXPLAIN SELECT * FROM table1 WHERE col1='test' AND col2='test'
Kết quả là:
id:1
select_type=SIMPLE
table:table1
type=ref
possible_keys:col1_co2_combined_index
key:col1_co2_combined_index
key_len:76
ref:const,const
rows:292004
Extra:Using where
Tôi đang sử dụng tuyên bố FORCE INDEX trong SP. Nhưng nó nhấn mạnh vào việc không sử dụng chỉ mục. Bất kỳ ý tưởng? Tôi nghĩ rằng tôi gần kết thúc :)
Có thể là sau khi thực hiện các SP, MySQL đã lưu trữ kết quả, và sau đó khi bạn thực hiện nó bên ngoài SP, nó chỉ đánh bộ nhớ cache hơn là thực hiện nó một lần nữa. –
Nhân tiện, tại sao 10 bảng có cùng cấu trúc? Tại sao không kết hợp chúng thành 1 bảng? –
thiết kế cơ sở dữ liệu là ra khỏi bàn tay của tôi tôi sẽ không bao giờ làm thiết kế như vậy :) đầu tiên tôi thực hiện các truy vấn với tham số khác nhau sau đó ngay lập tức tôi gọi sp với cùng một tham số. kết quả tương tự. có vẻ như sp thậm chí không lấy kết quả từ bộ nhớ cache. – bselvan