-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unreadテーブルにchannel_idカラムを追加 #1746
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
大体よさそう
ちょっと今忙しいので代案についてはあとで考えます |
|
なるほど、ありがとうございます。 僕もゆがんだデータ構造に対して忌避感を持っていて、その理由としてはメンテナンスコストがかなり増大するからです。 特に今回の場合、PRIMARY KEYが通常用いられる"一意に特定するためのキー"でなく"ソートするためのキー"(created_at)として用いられているのが僕の忌避間の原因だと考えています。 メンテナンスコストの面でいうと、PRIMARY KEYにcreated_atが存在するのが今回の場合ある種非自明で、今後(ほかの人が)この周辺の処理をいじる際に毎回このPRの経緯を見て理解する必要が出てくる(もしくはSQLを見て必要性を理解する)コストが発生するのが懸念点だと感じています。 ここに関しては速度とコストのトレードオフなのでどちらを取るかはお任せします。 僕の意見としては、数ms程度の遅延なら許容かなと考えています 補足:
時系列データなど時間そのものがPRIMARYな属性を持っているような連続データな場合はその限りではないですが、今回はそうではないとの認識です |
なんかちゃんと書いたら激怖文章になっちゃった、言葉固すぎ? |
いや、僕は慣れてるからいいよ 今までこの「気持ち悪さ」・「忌避感」が感覚でしか話されてなかったから、メンテナンスコストの話は納得感ありました、ありがとう 2人から異論が唱えられたのもあって、だいぶ迷ってますねぇ |
これ内側から実行されるから |
いやSelectのほうが後だから、GROUP_BYはかかってるのか? |
サブクエリの SQL筋不足です |
SELECT
m.channel_id AS channel_id,
COUNT(m.id) AS count,
MAX(u.noticeable) AS noticeable,
MIN(m.created_at) AS since,
MAX(m.created_at) AS updated_at,
(
SELECT message_id
FROM unreads u2
WHERE user_id = ? AND created_at = MIN(u.created_at)
) AS oldest_message_id
FROM unreads u
JOIN messages m ON u.message_id = m.id
WHERE u.user_id = ?
GROUP BY m.channel_id; 一応これで、今のmasterのコードの1/5の実行時間にはなりました |
結構気になってるのはそのサブクエリ、GROUP_BYされた各行に対して実行されてる気がするから(最適化かかったらどうなるか知らないから曖昧なことしか言えない) |
早いのか動くのかもわからんけどとりあえず
SELECT
m.channel_id AS channel_id,
COUNT(m.id) AS count,
MAX(u.noticeable) AS noticeable,
MIN(m.created_at) AS since,
MAX(m.created_at) AS updated_at
FROM (
SELECT * FROM unreads WHERE unreads.user_id = ?
) AS u
JOIN messages m ON u.message_id = m.id
GROUP BY m.channel_id; SELECT t.message_id, t.channel_id, t.created_at, ROW_NUMBER() OVER (PARTITION BY t.channel_id ORDER BY t.created_at ASC) AS row_num
FROM (
SELECT u.channel_id AS channel_id, u.message_id AS message_id, m.created_at AS created_at FROM (
SELECT * FROM unreads WHERE u.user_id = ?
) AS u
JOIN messages m ON u.message_id = m.id
WHERE m.channel_id IN (?)
) AS t
WHERE row_num=1; |
WINDOW関数8.0空だったわ |
でも普通に分割したほうがいいと思います |
あとこれchannel_id単体にindexついてないけど大丈夫だっけ |
pikachuくんのでもサブクエリ別にすれば普通に早くなると思います |
一クエリならサブクエリとメインクエリ入れ替えるとサブクエリ発行回数が一回になって早くなると思うけど普通に読みにくいし別呼び出しがいいと思う |
9a161ea
to
6db39b4
Compare
af677d9
to
b631c9d
Compare
メモ: 現時点でマイグレーションは手元45分 |
余分になった未読を削除するように
メモ: 現時点でマイグレーションは手元15分弱 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
いくつか
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Migrationの動作確認が取れていればよさそう
resolve #1437 ?
#1737 にて、同条件でのクエリ実行時間が0.09秒→5秒となったことを受けて。
現在のテーブル構造ではどうクエリを効率化しても0.9秒程度になってしまい、前から言われていたレイテンシの問題が深刻化することが予想されるため、なんとかしようとした