2016-08-02 12 views
1

だから私はこのコードスニペットをここに見つけました。それは本質的にMySQLのための "row_number()"関数を偽造します。それは私が好きで必要な非常に高速で実行されますが、最後にwhere句を使用することはできません。エイリアス化された列でこのクエリを高速化するにはどうすればよいですか?

select 
    @i:[email protected]+1 as iterator, t.* 
from 
    big_table as t, (select @i:=0) as foo 

where iterator = 875に追加するとエラーが発生します。

上記のスニペットは約.0004秒で実行されます。私はサブクエリとして別のクエリ内でそれをラップすることができますが、それは痛いほど遅くなります。

select * from (
    select 
    @i:[email protected]+1 as iterator, t.* 
    from 
    big_table as t, (select @i:=0) as foo) t 
where iterator = 875 

上記のスニペットは実行に10秒以上かかる。

とにかくこれをスピードアップするには?

+0

サブクエリにしない限り、where句でエイリアス化された列を使用することはできません。 – 1000111

+0

ええ、それは私がそれをサブクエリーにすると実現するのですが、スピードは非常に悪くなります(サブクエリーで.0004秒、別の '選択'内に10秒を入れると)。 質問が更新されました。 – MikelG

答えて

2

あなたはWHEREとしてLIMITを使用することができます。

select 
    @i:[email protected]+1 as iterator, t.* 
from 
    big_table as t, (select @i:=874) as foo 
LIMIT 875,1 

あなたが唯一のレコード875をしたいので、これは速いだろう。

+0

本当に速い! .0007秒。この私の友人と....あなたは私にMySQLの "ランダムな"問題を解決するための断片を与えました。ありがとうございました! – MikelG

1

お試しください。

where句の変数の値を大きくして、それを875と照合すると、このトリックが実行されます。

SELECT 
    t.* 
FROM 
    big_table AS t, 
    (SELECT @i := 0) AS foo 
WHERE 
    (@i :[email protected] + 1) = 875 
LIMIT 1 

注意:あなたはあなたが希望行番号を持つ同じ行を毎回取得するという保証はないですORDER BY句を指定しない限り

。テーブルのデータは順序付けられていないセットなので、MySQLはこれを保証しません。

したがって、some fieldに注文を指定すると、その特定のレコードを取得するためにユーザー定義変数は必要ありません。

SELECT 
    big_table.* 
FROM big_table 
ORDER BY big_table.<some_field> 
LIMIT 875,1; 

some_fieldがインデックス化されている場合は、パフォーマンスを大幅に向上させることができます。この場合

+0

これははるかに優れていますが、まだ少し遅いです。クエリの実行には1.4秒かかります。私はMySQLの専門家ではないので、これをスピードアップするために使用できるトリックはありますか? – MikelG

+0

最後に1を加えた後の実行時間を教えてください。 (回答更新) – 1000111

+0

.0007秒!これも同様に動作します!私は2つの作業ソリューションを数回実行し、その時間を平均します。 – MikelG

関連する問題