あなたの質問は、すべての雇用主のすべての雇用についてカウントを返すべきですが、表示するために一致させるべき基準がいくつかあります。使用している暗黙的な結合は、INNER JOINです。これには、行を含めるためにすべての条件を一致させる必要があります。これは、 "isActive"、 "beenActive"、 "status = 1"のジョブだけを返すことを意味し、createdAtは過去に30日未満であり、雇用者は "isActive"と "status = 1"です。あなたのデータが正しいかどうか確認してください。
SELECT c.id AS employerID, count(*) as total
FROM employer as c, job as j
WHERE c.isActive=1 AND c.status=1
AND j.employerIDFK = c.id
AND j.isActive=1
AND j.beenActive=1
AND j.status=1
AND DATE_ADD(j.createdAt, INTERVAL 30 DAY) > NOW()
GROUP BY c.id
限り他の人がcreatedAtのフィルタについて言うしようとしているものと、MySQLは最初の()(一度だけ)NOW評価します。次に、createdAt日付に30日を追加して、NOW()より大きいかどうかを確認します。 MySQLは自動的にこれを自動的に最適化しますが、これはお使いのバージョンやその他の要因によって異なりますが、一般に、行ごとにcreatedAtの日付に対して一定の式と比較する関数を実行すると、 createdAtカラム
だから、あなたは変換する必要があります。これに
AND DATE_ADD(j.createdAt, INTERVAL 30 DAY) > NOW()
を:
AND j.createdAt > DATE_ADD(NOW(), INTERVAL -30 DAY)
これは、プレーン列としてj.createdAt列を離れるので、MySQLは今見つけるために列に対して任意のインデックスを利用することができます。過去30日以内の日付。
100人の部屋に立って、誕生日に30日を追加して、計算された日付を今日に求める人に尋ねるのと同じです。あなたはただ100人を働かせました。代わりに、今日の日付から30日を引いて基準を事前に計算し、誰かの誕生日がその日付よりも大きいかどうかを尋ねるだけです。 1回の計算で済むだけで、100人の人が苦労しなくて済むようになりました。
出典
2012-04-28 10:59:48
Ami
このクエリについては、私にはいくつかのことがあります。 1)適切な結合を使用します。暗黙的な結合は問題のトンを引き起こします(私はそれが実際にこれに関係していると考えています)。 2)NOW() - 30日を計算し、その値をj.createdAtと比較する。そうすれば、完全なテーブルスキャン(j.createdAtが索引付けされている場合)を回避できます。 – Corbin
私はまだ30日未満の仕事の完全なリストを取得する必要があります。私は今すぐ計算することによってあなたが意味することを知らないのですか? – Lalajee
NOW()の値は常に変化しているので、MySQLは各行ごとに再計算を比較する必要があります。つまり、DATE_ADDがなくても、フル・テーブル・スキャンが必要になります。基本的には、これは 'a + b
Corbin