2014年なんだからCOUNT(*)とかSQL_CALC_FOUND_ROWSとかLIMIT OFFSETのページングはやめようぜ

22
達人が教えるつぶあん🇺🇦 @kazeburo

2014年なんだからCOUNT(*)とかSQL_CALC_FOUND_ROWSとかLIMIT OFFSETのページングはやめようぜ

2014-03-06 13:10:10
MATSUO Masaru @localdisk

え、limit offset 使ったらダメなん? ページングってどうするのがイマドキなの?

2014-03-06 13:36:15
くわっちょ@社畜犬X @kuwaccho0711

@localdisk ダメと言われた経緯がわかりませんが、遅くなるからですかね? SQLでやるなら何らかのID使ってbetweenでやるとかでしょうか。

2014-03-06 13:48:21
MATSUO Masaru @localdisk

@kuwaccho0711 https://t.co/TNuRbYK2OS このツイートっす。今はどうするのがベストなんでしょう?

2014-03-06 15:37:11
Ryuta Kamizono @kamipo

@localdisk 件数が絞り込めない場合のCOUNTや大きなOFFSETが、少なくとも今のMySQLでは瞬時に結果を返せない重い処理になるので、重い処理だという前提で設計しましょうという意図だと思います。昔の資料ですが参考になれば http://t.co/ywMgiwmyd0

2014-03-06 18:18:52
oranie @oranie

今度はMySQLか・・・。頭がパンクしてきた。

2014-03-11 20:43:20
🐶Kazuhiro OSAWA @Yappo

SQL_CALC_FOUND_ROWS だめな理由がなんだっけ、っておもって試しに kazeburo SQL_CALC_FOUND_ROWS ってググると、ダメって事だけわかって便利

2014-03-11 20:53:28
🐶Kazuhiro OSAWA @Yappo

LIMIT OFFSET 使ってページングやってけるサービスってデータ少ないサービスっぽそうってのだけは、未来検索ブラジルのお陰で mysqld のソースコードレベルで知見を得ることができてる

2014-03-11 20:56:10
Ryuta Kamizono @kamipo

SQL_CALC_FOUND_ROWS は結局 COUNT してしまうから件数が多いと命取りなんで、どうしても COUNT しなきゃいけない作りなんだったら件数キャッシュするの検討してくれないとおじちゃん泣いちゃうって話だと思う。

2014-03-11 21:00:24
tagomoris @tagomoris

SQL_CALC_FOUND_ROWS って行全部読んじゃうから超おっせーという話かと思ってたけど、LIMIT以外の部分は行全体は読みにいかないの?

2014-03-11 21:04:50
Daisuke Maki @lestrrat

SQL_CALC_FOUND_ROWS 必要なので使ってるけど、この話題が出るたびに心が痛む

2014-03-11 21:07:05
CHIBA Masahiro @nihen

countがそもそも駄目って話はおいておいて、SQL_CALC_FOND_ROWSは、http://t.co/0wzLAX11xC このバグ踏んでからもう使うもんかってなりました

2014-03-11 21:09:44
Ryuta Kamizono @kamipo

@tagomoris いわゆる ORDER BY 狙いのインデックスを使えば LIMIT 分だけ行の読み込みすることができるんですが、そういうインデックスを使っていても SQL_CALC_FOUND_ROWS をつけると件数を数えるのにその条件での全行を読んじゃうんですよね。

2014-03-11 21:10:42
🐶Kazuhiro OSAWA @Yappo

SQL_CALC_FOUND_ROWS は最後まで読むんです

2014-03-11 21:12:21
yoku0825 @yoku0825

sql_calc_found_rows、「スキャンに強いMyISAM」時代の遺物感ある。

2014-03-11 21:16:40
達人が教えるつぶあん🇺🇦 @kazeburo

これは、、 RT @nihen: countがそもそも駄目って話はおいておいて、SQL_CALC_FOND_ROWSは、http://t.co/d7yDfKAOUK このバグ踏んでからもう使うもんかってなりました

2014-03-11 21:17:43
🐶Kazuhiro OSAWA @Yappo

Senna+Mysql は MyISAM だったけど SQL_CALC_FOUND_ROWS するとめっちゃ無駄なスキャン走ってパフォーマンスに問題でるのコード読んで把握したから、それスキップするパッチ書いたくらい重いんです http://t.co/Eu5kmu541u

2014-03-11 21:18:19
aska @su_aska

SQL_CALC_FOUND_ROWSしない #todo

2014-03-11 21:20:42
yoku0825 @yoku0825

sql_calc_found_rowsに限らず、結果がおかしくなる(特にパーティションが絡んだ時)のは5.6でいっぱい叩き出されてます。

2014-03-11 21:21:30
🐶Kazuhiro OSAWA @Yappo

要所を選んで SQL_CALC_FOUND_ROWS つかってもいいかもしれないんだけど、いつそのプロダクトを他人がメンテするようになって、何も考えないでうっかり使っちゃだめな所にコピペするか分からないので、結局は業務で SQL_CALC_FOUND_ROWS を使わないのが正解

2014-03-11 21:22:09
Ryuta Kamizono @kamipo

確かめないで言ってるけど、例えば1行がテキスト数百文字ぐらいのでかいテーブルで参照に偏りがある(最近の行にしかほぼ参照が行かない)場合、ORDER BY狙いのインデックスで必要な行だけ取ってきてCOUNTはカバリングインデックス狙ったほうがバッファが汚れなくていいと思う。

2014-03-11 21:22:10
🐶Kazuhiro OSAWA @Yappo

ああ、この senna のぱっち SQL_CALC_FOUND_ROWS とか LIMIT OFFSET なページングするな。の理由全部説明できてるな

2014-03-11 21:24:46
🐶Kazuhiro OSAWA @Yappo

ちなみに WHERE id > ? ORDER BY id LIMIT ? な感じのクエリをはける感じの UI 設計をするとスケールするのでおすすめですよ

2014-03-11 21:28:56
🐶Kazuhiro OSAWA @Yappo

ミドルウェアで実装されてる機能はなるべく開発しゃとかみんなが使ってるもので、必要最小限にすると安定するっていうの Senna と Q4M が僕に教えてくれた

2014-03-11 21:31:25