SQLの高速化について質問です。
とあるselect文でメモリが足りません。。
実現したい事は
最終ポイント獲得日が180日以前だったユーザーを抽出です。
最終的な形としては
Array ( [0] => Array ( [id] => 2 [user_id] => 2 [point] => 387 [max_date] => 1535727600 ) [1] => Array ( [id] => 5 [user_id] => 4 [point] => 1261 [max_date] => 1535727600 ) )
このような感じで、配列で取り出せれば理想です。
現在の環境
CREATE TABLE `test_point_history` ( `id` int(11) NOT NULL, `user_id` int(11) NOT NULL, `point` int(11) NOT NULL, `date` int(11) NOT NULL, `expire_date` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `test_point_history` (`id`, `user_id`, `point`, `date`, `expire_date`) VALUES (1, 1, 1320, 1519830000, NULL), (2, 2, 387, 1522508400, NULL), (3, 2, 1716, 1525100400, NULL), (4, 1, 1717, 1527778800, NULL), (5, 4, 1261, 1530370800, NULL), (6, 1, 1304, 1533049200, NULL), (7, 2, 1031, 1535727600, NULL), (8, 3, 420, 1538319600, NULL), (9, 4, 168, 1535727600, NULL), (10, 1, 1859, 1540998000, NULL), (11, 1, 1637, 1543590000, NULL), (12, 1, 1125, 1551366000, NULL), (13, 3, 219, 1551366000, NULL);
このテーブルには獲得したポイントを履歴に残すテーブルです。
現在やりたい事は実現できているのですが、実データーは1000万件を超えるので、メモリーエラーになってしまいます。
メモリーの上限値を変更する前にSQLを見直ししたいと思います。
現在実行しているSQL
SELECT `id`, `user_id`, `point`, MAX(date) as max_date FROM `test_point_history` WHERE `expire_date` IS NULL GROUP BY `user_id` HAVING `max_date` <= (UNIX_TIMESTAMP() - 15552000)
以上になります。ご教授宜しくお願いします!
2019/05/21 13:30 追記
配列の時点でメモリーエラーでは?とご意見いただきましたので、SQL文を発行している箇所を追記します。
php
1$this->db = $this->load->database('db_slave', true); 2 3 $this->db->select('user_id,MAX(date) as max_date')->from('point_history_copy'); 4 $this->db->where("expire_date <=", 0); 5 $this->db->group_by('user_id'); 6 $this->db->having('max_date <= (' . $this->time . ' - 15552000)'); 7 $array = $this->db->get()->result_array(); 8 9 return $array; 10//↑returnされる前にメモリーが足りなくてエラーが出ます。
そして現在
php.iniのmemory_limmitは256MBでした。
回答7件
あなたの回答
tips
プレビュー