社内で「redisのリスト型は数が多くなると重くなるのか」という議題が上がり、実際に検証してみました。
そもそもRedisとは
メモリで管理するデータベースです。高速ですが、SQLのようにデータをテーブルとしてまとめるのは苦手。
以下の条件で検証します。
※なお、今回要素に書き込む値は全て「true」です。検証単位は秒で、同じ命令を100回繰り返してるので、実際はもっと早いです。
・要素数0のリスト型に100回データを追加する
・要素数100のリスト型に100回データを追加する
・要素数200のリスト型に100回データを追加する
……
・要素数900のリスト型に100回データを追加する
要素数の数に応じて追加速度が遅くなるなら、速度は低下するはずですが…
| 検証結果 | |
|---|---|
| 0~100 | 0.0028040409088135 |
| 100~200 | 0.0028679370880127 |
| 200~300 | 0.0027220249176025 |
| 300~400 | 0.0028030872344971 |
| 400~500 | 0.0024170875549316 |
| …… | |
| 2900~3000 | 0.0027751922607422 |
多少ばらつきはあるものの、要素数によって速度が落ちる傾向はないようです。今回はLpush、Rpushで試しましたが、そこまで違いはありませんでした。
要素数が多いほど全件参照速度は遅くなるのか。
以下の条件で検証します。
・要素数0で全件参照を100回行う
・要素数500で全件参照を100回行う
・要素数1000で全件参照を100回行う
・要素数1500で全件参照を100回行う
・要素数2000で全件参照を100回行う
・要素数2500で全件参照を100回行う
・要素数3000で全件参照を100回行う
各方法で10回おこない、最速時間で比較します。
| 検証結果 | |
|---|---|
| 要素数0 | 0.0025110244750977 |
| 要素数500 | 0.016954898834229 |
| 要素数1000 | 0.031013011932373 |
| 要素数1500 | 0.046410083770752 |
| 要素数2000 | 0.06744909286499 |
| 要素数2500 | 0.086562871932983 |
| 要素数3000 | 0.13561391830444 |
| 要素数4000 | 0.17251300811768 |
| 要素数5000 | 0.23781895637512 |
| 要素数10000 | 0.51502299308777 |
要素数の数に比例して増えるのではなく、数が増える程、遅延も増えるようです。要素の増やしすぎは危険ですね。
要素数が多いほど、単体参照速度は遅くなるのか
先ほどの例では全件参照するので、その分当然遅くなりますが、では数ある要素の中からインデックスを指定して1つだけ取得する場合はどうでしょうか?
以下の条件で検証します。
・要素数1000で500件目の要素を参照を100回行う
・要素数1500で750件目の要素を参照を100回行う
・要素数2000で1000件目の要素を参照を100回行う
……
・要素数5000で2500件目の要素数を参照を100回行う
| 検証結果 | |
|---|---|
| 要素数500 | 0.0033140182495117 |
| 要素数1000 | 0.002723217010498 |
| 要素数1500 | 0.0029160976409912 |
| 要素数2000 | 0.0030660629272461 |
| 要素数2500 | 0.0031499862670898 |
| 要素数3000 | 0.0033440589904785 |
| 要素数5000 | 0.0034210681915283 |
| 要素数10000 | 0.0043261051177979 |
要素数に応じて若干負荷が増えていくものの、全件取得に比べると圧倒的に早いことが分かりました。
要素数に応じて、要素数の取得速度は遅くなるのか
要素数の内容を全件取得すると速度が極端に遅くなりましたが、要素数の取得は遅くなるのでしょうか?
以下の条件で検証します。
・要素数0で要素数の取得を100回行う
・要素数1000で要素数の取得を100回行う
・要素数2000で要素数の取得を100回行う
・要素数3000で要素数の取得を100回行う
……
・要素数10000で要素数の取得を100回行う
| 検証結果 | |
|---|---|
| 要素数0 | 0.0023350715637207 |
| 要素数1000 | 0.002424955368042 |
| 要素数2000 | 0.0023620128631592 |
| 要素数3000 | 0.0023491382598877 |
| 要素数5000 | 0.0026330947875977 |
| 要素数10000 | 0.0022468566894531 |
要素数が増えても、速度はそこまで変わらないようです。
検証結果
今回の検証の結果、リスト型からランダムに値を1回取得する場合、全件参照して取得したデータ配列の中からランダムに選ぶよりも、要素数を取得後、0から要素数の間のランダムな数字を選択し、単体参照する方が圧倒的に速いことが分かりました。
前者の場合、1万件を全件取得の時点で0.515秒かかりますが、後者の場合、要素数を取得(0.002秒)+単体取得(0.0043秒)なので、速度が段違いです。
