Bảng MySQL với 100.000 bản ghi được truy vấn thường xuyên


11

Tôi có một cơ sở dữ liệu duy nhất gồm khoảng 100 bảng để lưu trữ các loại thông tin khác nhau.

Bảng quan trọng nhất là bảng đơn hàng của chúng tôi được sử dụng để lưu trữ đơn đặt hàng của khách hàng và hiện có hơn 100000 hồ sơ.

Bảng này là bảng được yêu cầu nhiều nhất trong cơ sở dữ liệu của chúng tôi, cho các phần thông tin khác nhau cần thiết từ bảng điều khiển theo thứ tự thời gian thực, số liệu thống kê, phân tích, v.v.

Tôi theo dõi cơ sở dữ liệu một cách thường xuyên và có các truy vấn chậm được kích hoạt trên cơ sở dữ liệu để theo dõi các vấn đề.

Tôi sử dụng các tập lệnh như mysqltuner để đưa ra truy vấn hàng ngày.

Tôi cũng sử dụng mysqlsla để thu thập thông tin về 10 truy vấn chậm nhất trong cơ sở dữ liệu của chúng tôi.

sample stat
Count         : 11.48k  (30.66%)
Time          : 19.623758 s total, 1.709 ms avg, 239 µs to 2.475017 s max  (18.64%)
  95% of Time : 5.246833 s total, 481 µs avg, 239 µs to 1.095 ms max
Lock Time (s) : 14.460071 s total, 1.259 ms avg, 53 µs to 2.462555 s max  (41.38%)
  95% of Lock : 806.43 ms total, 74 µs avg, 53 µs to 137 µs max
Rows sent     : 1 avg, 0 to 9 max  (0.99%)
Rows examined : 6 avg, 1 to 28 max  (0.15%)

Hầu hết các câu hỏi chậm nhất liên quan đến bảng thứ tự được đề cập ở trên. Tôi sử dụng MyISAM làm công cụ lưu trữ của mình để các vấn đề có thể xảy ra:

  1. Khóa bảng
  2. Vấn đề lập chỉ mục

Làm cách nào tôi có thể cải thiện các số liệu thống kê này, tôi đã lập chỉ mục cho các bảng này và đã tiếp tục điều chỉnh chúng để cải thiện các truy vấn đọc.

Lược đồ bảng

`orderid` int(11) NOT NULL AUTO_INCREMENT,
`cityid` tinyint(3) unsigned NOT NULL DEFAULT '1',
 `model_type` tinyint(1) unsigned DEFAULT '1',
`userid` int(11) DEFAULT NULL,
`usertype` char(1) DEFAULT NULL,
`time` time DEFAULT NULL,
`ordercode` char(8) DEFAULT NULL,
`restid` smallint(3) unsigned NOT NULL,
`areaid` smallint(3) unsigned DEFAULT NULL,
`restname` varchar(50) DEFAULT NULL,
`date` date NOT NULL,
`del_time` time NOT NULL,
`status` tinyint(3) unsigned NOT NULL,
`amount` float NOT NULL,
`deliverycharge` smallint(4) unsigned DEFAULT '0',
`tax` float NOT NULL,
`total` float NOT NULL,
`extras` varchar(255) DEFAULT NULL,
`requests` varchar(255) DEFAULT NULL,
`discount` float DEFAULT NULL,
`rdiscount` float DEFAULT NULL,
`reason` varchar(255) DEFAULT NULL,
`rest_order` tinyint(1) unsigned DEFAULT NULL,
`admin_user` varchar(25) DEFAULT NULL,
`mode` char(1) NOT NULL,
`priority_order` tinyint(1) unsigned DEFAULT '0',
`payment_mode` tinyint(1) unsigned DEFAULT '0',
`km` tinyint(3) unsigned DEFAULT NULL,
`order_type` tinyint(1) NOT NULL DEFAULT '1',
`coupon_discount` smallint(3) DEFAULT '0',
`pickup_time` time NOT NULL,
PRIMARY KEY (`orderid`),
KEY `cityid` (`cityid`),
KEY `date_3` (`date`,`status`,`mode`),
KEY `orderid` (`orderid`),
KEY `time` (`time`),
KEY `userid` (`userid`,`usertype`),
KEY `restid` (`restid`,`date`,`status`)

truy vấn nhật ký chậm

SELECT `a`.`orderid`, `a`.`date`, `a`.`status`, `a`.`restname`, `a`.`admin_user`, `a`.`model_type`, `b`.`name` as cityname
FROM `tk_order_queue` AS a
INNER JOIN `tk_cities` AS b ON `a`.`cityid` = `b`.`id`
WHERE `a`.`date` =  '2012-06-30'
AND `a`.`status` =  0
AND `a`.`mode` =  1
ORDER BY `a`.`orderid` desc;

Vui lòng chạy SHOW CREATE TABLE orders\Gvà gửi câu hỏi đó trong câu hỏi
RolandoMySQLDBA

2
Tôi đang đọc không chính xác hay thời gian truy vấn trung bình là 1,7ms? Tại sao trên trái đất bạn sẽ tìm cách tăng tốc?
Philᵀᴹ

Tôi hơi bối rối về việc tại sao nó xuất hiện trong nhật ký truy vấn chậm.
sheldon

@RolandoMySQLDBA tôi đã đính kèm lược đồ
sheldon

1
Chỉ vì bạn có các chỉ mục trên bảng không có nghĩa là chúng là các chỉ mục phù hợp cho các truy vấn của bạn. Bạn có thể đăng một vài ví dụ về các truy vấn chậm và đầu ra EXPLAIN của họ không? Ngoài ra, mức độ thường xuyên được cập nhật bảng đơn hàng?
bobwienholt

Câu trả lời:


8

Bạn sẽ phải so sánh các mệnh đề WHERE và các câu lệnh GROUP BY và ORDER BY của tất cả các truy vấn của bạn để đảm bảo các chỉ mục hiện tại của bạn có thể hỗ trợ chúng trong các kế hoạch GIẢI THÍCH của chúng.

Hôm qua, tôi đã trả lời câu hỏi này: InnoDB vs MyISAM với nhiều chỉ mục

Trong câu hỏi đó, tôi đã đề nghị làm một cái gì đó cho bảng MyISAM mà bạn cũng có thể làm

ALTER TABLE orders ROW_FORMAT=Fixed;

Điều này sẽ coi tất cả các VARCHAR là CHARs. Mỗi hàng sẽ có cùng độ dài. Điều này sẽ tăng dung lượng đĩa 80% -100%. Bảng của bạn sẽ phình to đến kích thước tối đa cho bố cục hàng nhân với số lượng hàng. Bảng của bạn có thể tăng gấp đôi hoặc gấp ba kích thước.

Lợi ích ở đâu? Bảng MyISAM của bạn sau đó sẽ được đọc từ / ghi đến bất cứ nơi nào nhanh hơn từ 20% - 30% mà không thay đổi bất cứ điều gì khác.

Tôi đã học được điều đó từ các trang 72,73 từ Thiết kế và Điều chỉnh Cơ sở dữ liệu MySQL .

Tôi đã viết về điều này trong quá khứ:


Cảm ơn đã giải thích chi tiết, có, các chỉ mục được thêm vào bảng dựa trên các truy vấn được sử dụng cho các lựa chọn, nhóm theo và sắp xếp theo các câu lệnh được sử dụng trong hệ thống của chúng tôi. Đã theo dõi các truy vấn mà không có nhật ký chỉ mục và đang cập nhật các bảng tương ứng.
sheldon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.