create table sample (no int, data int, ccess timestamp);
insert into sample (no) value (1);
insert into sample (no) value (2);
insert into sample (no) value (3);
;
レコード毎のdataを更新する毎にaccessに更新日が上書きされるとします。
更新日が7日以内のものがどのnoであるかを検索したいのですが、
毎回、以下のようにno毎に該当するものがあるかどうかを検索する方法では効率が悪いと思います。
SELECT COUNT(*) FROM sample WHERE no=1 AND (accessat > "2011-02-13 11:45:20" - INTERVAL 7 DAY);
SELECT COUNT(*) FROM sample WHERE no=2 AND (accessat > "2011-02-13 11:45:20" - INTERVAL 7 DAY);
SELECT COUNT(*) FROM sample WHERE no=3 AND (accessat > "2011-02-13 11:45:20" - INTERVAL 7 DAY);
;
1回の方法で実現するよい方法がございましたら、ご教授をお願いいたします。
一度に計算させたいのであれば下記のような具合にGROUP BYを用いると良いでしょう
SELECT no, COUNT(*) FROM sample WHERE no IN (1,2,3) AND (accessat > "2011-02-13 11:45:20" - INTERVAL 7 DAY) GROUP BY no ;
余談になりますが、ミドルウェア側(phpなど)で日付をあらかじめ計算することとして、
MySQLには下記のようなSQLを投げるようにすれば、MySQL側での日付計算が省かれ、処理速度が向上します
SELECT no, COUNT(*) FROM sample WHERE no IN (1,2,3) AND (accessat > "2011-02-06 11:45:20") GROUP BY no ;
noとaccessatでインデックスを作成しておくことも合わせると処理はさらなる高速化が期待できますが、
更新処理が激しい場合には逆にインデックスが足かせになる場合もありますので、
インデックスを作成するかどうかはテストデータを大量に用意してやってみないことには絶対とは言えません
一度に計算させたいのであれば下記のような具合にGROUP BYを用いると良いでしょう
SELECT no, COUNT(*) FROM sample WHERE no IN (1,2,3) AND (accessat > "2011-02-13 11:45:20" - INTERVAL 7 DAY) GROUP BY no ;
余談になりますが、ミドルウェア側(phpなど)で日付をあらかじめ計算することとして、
MySQLには下記のようなSQLを投げるようにすれば、MySQL側での日付計算が省かれ、処理速度が向上します
SELECT no, COUNT(*) FROM sample WHERE no IN (1,2,3) AND (accessat > "2011-02-06 11:45:20") GROUP BY no ;
noとaccessatでインデックスを作成しておくことも合わせると処理はさらなる高速化が期待できますが、
更新処理が激しい場合には逆にインデックスが足かせになる場合もありますので、
インデックスを作成するかどうかはテストデータを大量に用意してやってみないことには絶対とは言えません
ご提案の方法で目的が実現できました。ありがとうございました。
ただしご指摘とおり実運用では更新間隔が多いので、処理の高速化というよりは手順の効率化が目的としました。
そういう意味では、2つ目のご回答はとてもありがたいです。
参考にさせていただきます。ありがとうございました。
SELECT no,COUNT(*) FROM sample WHERE (access > "2011-02-13 11:45:20" - INTERVAL 7 DAY) GROUP BY no ORDER BY no;
ご提案の方法で目的が実現できました。ありがとうございました。
ご提案の方法で目的が実現できました。ありがとうございました。
ただしご指摘とおり実運用では更新間隔が多いので、処理の高速化というよりは手順の効率化が目的としました。
そういう意味では、2つ目のご回答はとてもありがたいです。
参考にさせていただきます。ありがとうございました。