私は次のクエリを最適化することを任されています。`from_unixtime`はこのクエリを遅くすることができますか?
select
c.account_key,
c.cohort,
date(concat(year(from_unixtime(min(f.processdate_est_key))), '-',
month(from_unixtime(min(f.processdate_est_key))), '-1')) as
customer_conversion_month
from
bidw_stage.cohort c left join
bidw.fact f
on
c.account_key = f.account_key and
f.usage_dollars != 0 and
12 * (year(from_unixtime(f.processdate_est_key)) - year(c.cohort)) +
(month(from_unixtime(f.processdate_est_key)) - month(c.cohort)) >= 2
group by c.account_key, c.cohort;
昨年1月に完了するまでに30秒かかりました。今はほぼ3分かかります。ファクトテーブルには約3,000万レコードが含まれ、コホートテーブルは約20kです。ファクト表属性 'account_key'は索引付けされていますが、「コホート」表にはありません。
私はこのクエリを記述していないと、これは、クエリを遅くすることでしたオリジナルのコーダは、この
12 * (year(from_unixtime(f.processdate_est_key)) - year(c.cohort)) +
(month(from_unixtime(f.processdate_est_key)) - month(c.cohort))
理由について何らの文書を残していませんか?どのようにこれを最適化できますか?
カラムで関数を使用すると、インデックスを決して使用できません。インデックスは生の(操作されていない)カラムデータにのみ適用されます –
計算カラムにWHEREがあるものは通常テーブルスキャンが必要なので、性能は残酷になります。これらの列をネイティブの 'DATETIME'形式に切り替えることができれば、半分になります。これらの値の代わりに['DATE_SUB()'](https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-sub)を使用することができますこの式。 – tadman
参考までに、 'processdate_est_key'が少なくとも' cohort'の後の2ヶ月目にあるかどうかチェックします。したがって、 'cohort'が2017年2月にあった場合、2017年4月以降の' processdate_est_key'に当てはまります。 – Barmar