Tabel MySQL dengan 100.000 catatan sering ditanyakan

11

Saya memiliki database tunggal sekitar 100 tabel untuk menyimpan berbagai jenis informasi.

Tabel yang paling penting adalah tabel pesanan kami yang digunakan untuk menyimpan pesanan pelanggan dan lebih dari 100.000 catatan seperti sekarang dan terus bertambah.

Tabel ini adalah tabel yang paling banyak ditanyakan dalam basis data kami, untuk berbagai bagian informasi yang dibutuhkan dari dasbor pesanan waktu nyata, statistik, analitik, dll.

Saya memantau database secara teratur dan memiliki permintaan yang lambat diaktifkan pada database untuk melacak masalah.

Saya menggunakan skrip seperti mysqltuner untuk memuntahkan kueri setiap hari.

Saya juga menggunakan mysqlsla untuk mengumpulkan informasi tentang 10 kueri paling lambat di database kami.

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%)

Sebagian besar pertanyaan paling lambat melibatkan tabel urutan yang disebutkan di atas. Saya menggunakan MyISAM sebagai mesin penyimpanan saya sehingga masalah yang mungkin terjadi adalah:

  1. Mengunci meja
  2. Masalah pengindeksan

Bagaimana saya bisa meningkatkan statistik ini, saya sudah mengindeks untuk tabel ini dan terus mengubah mereka untuk meningkatkan kueri baca.

Skema tabel

`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`)

permintaan log lambat

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;
Sheldon
sumber
Silakan jalankan SHOW CREATE TABLE orders\Gdan posting itu dalam pertanyaan
RolandoMySQLDBA
2
Apakah saya salah membaca, atau rata-rata waktu permintaan 1,7 ms? Mengapa Anda ingin mempercepat itu?
Philᵀᴹ
Saya sedikit bingung mengapa itu muncul di log permintaan lambat.
sheldon
@RolandoMySQLDBA saya telah melampirkan skema
sheldon
1
Hanya karena Anda memiliki indeks di atas meja tidak berarti mereka adalah indeks yang tepat untuk kueri Anda. Bisakah Anda memposting beberapa contoh permintaan lambat dan output EXPLAIN mereka? Juga, seberapa sering tabel pesanan diperbarui?
bobwienholt

Jawaban:

8

Anda harus membandingkan klausa WHERE dan GROUP BY dan ORDER BY pernyataan semua pertanyaan Anda untuk memastikan indeks Anda saat ini dapat mendukung mereka dalam rencana EXPLAIN mereka.

Kemarin, saya menjawab pertanyaan ini: InnoDB vs MyISAM dengan banyak indeks

Dalam pertanyaan itu saya menyarankan untuk melakukan sesuatu pada tabel MyISAM yang dapat Anda lakukan juga

ALTER TABLE orders ROW_FORMAT=Fixed;

Ini akan memperlakukan semua VARCHAR sebagai CHAR. Setiap baris akan memiliki panjang yang sama persis. Ini akan menambah ruang disk 80% -100%. Meja Anda akan menggembung ke ukuran maksimum untuk tata letak baris dikalikan jumlah baris. Meja Anda bisa berukuran dua atau tiga kali lipat.

Di mana manfaatnya? Tabel MyISAM Anda kemudian akan dibaca dari / ditulis ke mana saja dari 20% - 30% lebih cepat tanpa mengubah apa pun.

Saya belajar itu dari halaman 72,73 dari Desain dan Tuning Database MySQL .

Saya telah menulis tentang ini di masa lalu:

RolandoMySQLDBA
sumber
Terima kasih atas penjelasan detailnya, ya indeks yang ditambahkan ke tabel didasarkan pada pertanyaan yang digunakan untuk pemilihan, grup oleh dan memesan dengan pernyataan yang digunakan dalam sistem kami. Telah memantau kueri tanpa log indeks dan memperbarui tabel yang sesuai.
sheldon