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

まとめました。
22
Masahiro 💺 @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
くわっちょ@社畜犬 @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
大沢和宏 @Yappo

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

2014-03-11 20:53:28
大沢和宏 @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
Masahiro Chiba @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
大沢和宏 @Yappo

SQL_CALC_FOUND_ROWS は最後まで読むんです

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

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

2014-03-11 21:16:40
Masahiro 💺 @kazeburo

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

2014-03-11 21:17:43
大沢和宏 @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
大沢和宏 @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
大沢和宏 @Yappo

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

2014-03-11 21:24:46
大沢和宏 @Yappo

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

2014-03-11 21:28:56
大沢和宏 @Yappo

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

2014-03-11 21:31:25
残りを読む(1)

コメント

大沢和宏 @Yappo 2014年3月11日
すごーい参考になる〜
0