SELECT
句で定義されたエイリアスを句で参照することはできませんが、句WHERE
で使用することはできますHAVING
。これは、集計関数が含まれている可能性があるため、WHERE
が前に評価されるためです。SELECT
SELECT
SELECT z1.id sid1,z2.id sid2,SQRT(POW(ABS(z1.col-z2.col),2) + POW(ABS(z1.row-z2.row),2)) r
FROM stars z1,stars z2
WHERE z1.id != z2.id
HAVING r <= 32
ORDER BY z1.id,z2.id
ただし、このHAVING
句はインデックスでは使用されない可能性が高いことに注意してください。WHERE
索引付けの目的で、節に近似用語を指定できます。
SELECT z1.id sid1,z2.id sid2,SQRT(POW(ABS(z1.col-z2.col),2) + POW(ABS(z1.row-z2.row),2)) r
FROM stars z1,stars z2
WHERE z1.id != z2.id
AND (z2.col BETWEEN z1.col-32 AND z1.col+32)
AND (z2.row BETWEEN z1.row-32 AND z1.row+32)
HAVING r <= 32
ORDER BY z1.id,z2.id
ボトルネックは算術計算ではなくディスク アクセスであることに注意してください。そのため、速度を最適化する場合は、WHERE を使用し、WHERE 句のみを最適化することをお勧めします。
ご了承ください
- x^2 は abs(x)^2 と同じです。
- x*x はおそらく pow(x,2) よりも高速です
- 平方根を計算する代わりに、反対側を平方できます。
試す:
SELECT z1.id sid1,z2.id sid2,
SQRT((z1.col-z2.col)*(z1.col-z2.col) + (z1.row-z2.row)*(z1.row-z2.row)) r
FROM stars z1,stars z2
WHERE z1.id != z2.id
AND (z1.col-z2.col)*(z1.col-z2.col) + (z1.row-z2.row)*(z1.row-z2.row) <= 1024
ORDER BY z1.id,z2.id