SQLでデータをソートする場合、SELECT句にORDER BYを指定するのが一般的です。しかし、そのソートはクエリーの処理を遅くしている原因かもしれません。ソート処理は、実は、SQLサーバーに大きな負荷をかけます。使い方を間違えると、システムの誤動作の原因になるかもしれません。そこで今回は、SQLにおけるソートの基本と、SQLにいるソートのやり方について解説します。
そもそもソートとは
SQLに限らず、コンピューターで大量のデータを扱う処理では、必ずと言っていいくらいソートを利用します。なお、コンピューター用語としてのソートとは、データの集合を一定の規則に従って並べ変える処理をさす言葉です。そして、日本語では整列、または、並び替えとも呼ばれます。次から、このようなソートの基本について紹介します。
ソートは歴史が古い
ビジネスでは、いろいろな用途で、目的に応じたデータの並び替えが行われています。そのため、ソートは、ビジネスにコンピュータが使われ始めた頃から、効率的な方法が研究され、情報システムを構成するプログラムなどに活用されてきました。
そのため、今使われているプログラム言語には必ずソートの機能があり、Excelなどのオフィスで使われるアプリケーションにも並び替えの機能が備わっています。中でも、ビジネスで使われることが多く、大量のデータを扱うデータベース管理ソフトでは、ソートがよく使われます。
ソートの実行は負荷がかかる
先ほど紹介したように、ソートはビジネスでよく利用されますが、データの量によっては大きな負荷がかかる処理です。数10個から数100個のテストデータでソートを含むSQLを処理したら一瞬で終わったとしても、データの数が数万個から数100万個に増えれば、かなり時間がかかることもあります。
これは、ソートのアルゴリズムが、全てのデータをメモリーに読み込んで、それらの全てのデータ同士を比較しなければならないからです。SQLを組む際、加工前の大量のデータに対してソートしたり、処理の途中でソートを実行してしまうと、処理に時間がかかり、システムが正常に動作しなくなることもあります。
SQLでソートを実行するには
多くのプログラム言語には、配列に格納したデータをソートするための関数が用意されています。しかし、SQLには、そのような関数が用意されている訳ではありません。SELECT句で抽出したデータを表示する際、ORDER BY で並び替えの条件を指定することで、ソートしたデータが得られる、という仕様です。
また、SQLでは、検索を早くするためにインデックスを作成できます。そして、SQLにおけるインデックスは、作成した際に自動でソートが適用されます。なお、このようなSQLにおけるソートの機能について、次から詳しく解説していきます。
SQLで出力をソートするORDER BYの基本
SQLでデータをソートする際に使うのがORDER BYです。これは、SQLの基本的な機能の1つのため、SQLが使えるデータベース管理ソフトなら、どれでも使えます。次から、ORDER BYの基本について紹介します。
ORDER BYの文法
ORDER BYは、SELECT句でデータを出力する際、ORDER BYに続く列名の値を対象にソートする機能です。なお、列名に続いてASCを指定すると昇順でソートし、DESCを指定すると降順でソートします。そして、ASCもDESCも指定しない場合は、昇順でソートです。
ORDER BYの基本
ORDER BY 列名 [ASC または DESC]
ORDER BYを使った例 SELECT col1 FROM table1 ORDER BY col1;
ORDER BYでソートする際の注意点
SQLのORDER BYでソートする際、指定された列が数字の場合は大小で、また、文字の場合はアルファベット順、または50音順でソートします。このようなORDER BYで注意が必要なのが、文字と数字が混在しているケースです。この場合、数字が文字として格納されている場合、数の大小ではなく、数字の並び順で出力されます。
文字と数字が混在している場合のソートの例 NO1 NO10 NO2 NO3 NO4
この例では、文字でソートしているため、3番目の文字が1のNO10が、3番目の文字が2のNO2よりも前にソートされます。このような添え字の数字でソートしたい場合は、数字の文字列を切り出し、数字に変換してソートすると良いでしょう。
ORDER BYはサブクエリーで使うべきではない
SQLでは、データベースに格納された列の他に、クエリーで作成したデータを使うことが可能です。そして、そのようなクエリーをサブクエリーと呼びます。このサブクエリーは、検索条件に合わせて調査対象を制限したり、文字を加工したりできる便利な機能です。
しかし、サブクエリーの結果のような途中のデータに対してソートを実行すると、その分、処理に時間がかかります。数を絞った上で最後にソートしたり、インデックスを活用するなどして、処理時間を短くするSQLを検討しましょう。
インデックスはソート済
大量のデータが格納されているテーブルに対して検索する場合、どうしても時間がかかってしまいます。しかし、インデックスを作っておくことで、検索時間の短縮が可能です。しかも、インデックスは、作成時に自動的にソートされて作られます。次から、このインデックスとソートの関係について解説します。
インデックスはクエリの実行を速くする
SQLにおけるインデックスとは、特定のテーブルを検索しやすくするために、指定した列のデータを並び替えしたリストを作成しておく機能です。なお、インデックス自体にデータは格納されていませんが、基になったテーブルの情報を効率良く参照できるので、検索時間を短縮できます。そして、SQLの中で列のように使える点が特徴です。
なお、インデックスを利用することで検索時間が短縮できるのは、予めソートされているがその理由です。また、基になったテーブルにデータが追加された場合、自動でソートされて格納されることから、検索時にソートを気にする必要がありません。
インデックス作成の基本
インデックスは、CREATE INDEX文で作成します。そして、構文は次のとおりです。
インデックス作成構文
CREATE INDEX “インデックス名” ON “テーブル名” (列名);
インデックスを作成するSQLの例 CREATE INDEX index_exp ON exp_table ( target );
上の例では、exp_tableというテーブルのtargetという列のインデックス、index_expを作成します。なお、列名は、複数指定することが可能です。
複数の列を対象としたインデックスを作成するSQLの例 CREATE INDEX index_tt ON exp_table ( t1, t2 );
上の例ではt1とt2という列のインデックス、index_ttを作成します。
インデックス利用時の注意点
先ほど解説したように、検索時間の短縮に効果があり、さらにソートを気にせずに使えるインデックスですが、使い方を間違えると効果が発揮できないケースもあります。例えば、インデックス作成時に指定した列を検索で使わないのに、検索用SQLで利用してしまうと、インデックスの効果が得られません。
そのためインデックスを利用する場合は、時間のかかるSQLの中でも、特に検索に時間がかかる列を見極めて使わなければ、効果が期待できないと考えてください。
まとめ
これまで解説したように、ビジネスで扱うデータはソートがよく使われており、そのようなデータを格納することの多いデータベース管理ソフトでは、order by句で簡単にソートできます。しかし、ソートはコンピュータにとって大きな負担がかかる処理です。特にデータが多い場合など、ソートに時間がかかり、システムが誤動作することもあります。
そのため、負荷のかかるソートは、サブクエリーでは使わずに、結果を出力する場合のみソートを適用するなど、ソートするタイミングに注意しましょう。また、ソート済のインデックスをうまく使うなどして、無駄に時間のかかるSQLを作成しないように注意しましょう。