• ベストアンサー

SQLの速度をあげるには・・・

テキストファイルからキーワードを拾って SQLをなげています SQLの質問になってしまうかもしれません いまはADO接続でやっています Open ファイル as input...... SQL = select * from tbl where name like '%キーワード%' execute(SQL) レコードセットの値で処理をいろいろ・・・ Loop もともとのDBの件数がものすごくおおくてselect文に結構な時間が かかってしまいます。速度をあげるほうほうってあるのでしょうか 私にはおもいつかなくて・・・ こういったほうほうは どう? ってのがありましたら おしえていただきたいのですが よろしくおねがいします。

  • ayato
  • お礼率25% (16/64)

質問者が選んだベストアンサー

  • ベストアンサー
  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.3

確かに・・・Like演算子・・・あまり使いたくないですね・・・ 文字列比較は処理を遅くさせるし、増してや「=」ではなくLikeですから、膨大な時間がかかる恐れが・・・ ちなみにぼく自身、DB系を多くしています。今の仕事もDB系なのですが、元となるホストは他の会社が行っており、それにあわせて作らなければなりません。 で、そのホスト連携部分に文字列を比較しなければならない部分があるんですよ・・・・ 自分の会社ならまだしも、他の会社がすでに設計済みのDBだから変えようがないのです。。。 まぁ愚痴っても仕方ないか・・・ なのでぼくも(不本意ながら)Like演算子を使用しています。 長い前置きはさておき・・・ 本題のSQLのスピードなのですが、 http://homepage2.nifty.com/inform/vbdb/addnew.htm こちらに面白い記述がありました。 AddNewにかかるスピードの検証で Access データベースの場合: AddNew のほうが INSERT INTO より5倍以上速い SQL Server の場合: INSERT INTO のほうが AddNew より 1.4倍 くらい速い とあります。 たぶんで物を言ってはいけないと思うけど、言っちゃいます。 (1)もしDBがアクセスで  >レコードセットの値で処理をいろいろ・・・  のところがUpdate用のSQL文で処理を行ってる場合  Recordsetをして、処理を行う (2)もしDBがアクセス以外で  >レコードセットの値で処理をいろいろ・・・  のところがRecordsetで処理を行ってる場合  Recordsetをせずに、UPDATE用のSQLを実行する 未検証なのですが多分イメージとして、こういうパターンが各DBに適してるのかな? すでにこのパターンなのであれば、意味ないですね(^^;)

参考URL:
http://homepage2.nifty.com/inform/vbdb/addnew.htm

その他の回答 (4)

  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.5

teebeeさん AccessでもADOで接続したら、ワイルドカードは%なんですよ。

  • teebee
  • ベストアンサー率68% (17/25)
回答No.4

ayato さん、こんばんは。 このSQLの書き方だと、ひょっとしてindexには期待できないのでしょうか... ワイルドカードが"%"ってことは、少なくともアクセスじゃないなぁとかひょっとしたらOracle?とか、想像で書いてますが、ワイルドカードを使った検索でindex使えるのって前方一致の時だけじゃないです? (有識者の方、間違ってたら指摘してください) likeを使わなくちゃいけないの?とか気になっちゃいます。 他の列をキーにして検索できたりしないのでしょうか? #なんか、逆に質問ばっかりになっちゃったみたいでごめんなさい。

  • zerosix
  • ベストアンサー率31% (47/149)
回答No.2

#1の方の通り、検索条件となるフィールドにインデックスを 作成することが一つあります。何でもつけていいというわけではありませんが。 また、プログラムの実装アルゴリズムですが、 DBの接続はSQLを発行するたびに接続しては遅いです。 さすがにayatoさんはつなぎっぱなしにしてますよね? 一度私はSQL発行ごとにDB接続をやってしまい、速度低下になってました(爆)。 また、検索条件があいまい検索をしなくてはいけないほど複雑なら、 テーブル設計に問題があることも考えられます。 ちょっとプログラムだけの話ではないですが、テーブル設計に問題がある可能性もあるということを知っていればいいかと思います。

  • masabou7
  • ベストアンサー率18% (2/11)
回答No.1

まず、likeを使ったあいまい検索は、全レコードを検索しますのでどうしてもパフォーマンスの低下が見られます。 可能であれば、使用を避けたほうが良いです。 その他には、テーブルに検索条件になるフィールドにインデックスを作成してみてはどうでしょうか。私の経験上かなりの改善が見られました。

関連するQ&A

  • SQL キーワード検索にて

    お世話になります。 DBからSQLでキーワードによる検索をかけるときですが、 二つ以上のワードがあるときに、一つのキーワードがほかのキーワードと かぶってしまう場合、例えば゛、『あいうえお』と『いうえ』等で絞り込むと、 結果的に『あいうえお』が含まれるものだけが該当しますが、これを、 『あいうえお』を含み、更にそれ以外にも『いうえ』が含まれるものを 絞り込むには、どうすればよいでしょうか。 つまり、『あいうえお』のみしか含まれないものは該当しないようにする方法です。 現在のSQLは、 (SELECT * FROM xxxx WHERE tablename LIKE '%あいうえお%' AND tablename LIKE '%いうえ%') のような感じです。 使用しているDBは、MySQL、SQLiteです。 何卒よろしくお願いいたします。

  • oracleのSQLパフォーマンスについて

    oracleのSQLパフォーマンスについて質問です。 当方、SQLは初めてで、ずぶの素人ですが、SQLパフォーマンスを改善することになりました。 質問の仕方も悪いとは思いますが、お力添えをいただきたいと思います。 【質問1】 DBのレコード件数は、SQLパフォーマンスにどう影響するでしょうか?以下例のようなことが知りたいです。 例1 INDEXのないテーブルに対しSQLを発行する場合、レコード件数の多いDBとレコード件数の少ないDBでは、レコード件数が少ない方が、パフォーマンスが良い? (前提として、検索対象DBは、レコード件数以外に差がないとする) 例2 WHERE句にINDEX項目を使用した場合、DBのレコード件数はパフォーマンスに影響しない (前提として、アクセスパスは適切で、検索対象をうまく絞り込むことができる) 例3 WHERE句にINDEX項目を使用したSQLをレコード件数の多いDBに発行する場合と、WHERE句にINDEX項目がないSQLをレコード件数の少ないDBに発行する場合では、どちらがパフォーマンスがよいのか (前提として検索対象DBは、レコード件数以外に差がないとする) 【質問2】 INDEXをDBに追加すると、INSERT、UPDATE、DELETEの際に、どのくらい影響するのでしょうか? 対象のDBは、5項目あり、400万件くらいのレコードがあります。また、複合項目(2項目)のプライマリキーと、単一INDEXがついており、新たに3項目の複合INDEXを追加しようとしています。 以上、よろしくお願いいたします。

  • PDOを使用し複数キーワードでOR条件のDB検索

    PDOを使用した複数キーワードでOR条件のDB検索をしたいです。 対象レコード件数が少ないので「LIKE '%hoge%'」で書こうと思うのですが下記の様にループで 書くしかないのでしょうか。 シングルクオートなどエスケープの処理を別で考えなければならず面倒なソースになってしまい、 他に良い方法が有りそうだけど、、と考えています。 初歩的な疑問ですが宜しくお願いします。 $serch_input = array('hoge','foo','""""') $input[] = prode(" " ,$serch_input) $sql = 'SELECT * FROM hoge WHERE '; foreach($input as $w) { $sql .= 'OR hoge.text LIKE "%' . $w . '%"'; } $result = connect()->query($sql); return $result;

    • ベストアンサー
    • PHP
  • 絞込みする時のSQLの書き方

    お世話になります。 絞込みする時のSQLの書き方について教えてください。 具体的には テーブル名tbl01,フィールド名f01,f02とした場合 1.f01もしくはf02にAという文字を含むレコードを抽出。 SQL = "select * from tbl01 where f01 like '%A%' or f02 like '%A%'" 2.続いて、1で抽出したデータからf01もしくはf02にBという文字を含むレコードを抽出するSQL文 SQL = ????? あくまでも、1と2を満たす条件を1つのSQL文で表す方法です。一旦、1の結果をワークテーブルに落とし、そこから2だけのSQL文を実行するわけではありません。

  • jspとsqlの連結したページ

    <%@ page import="java.sql.*" %> <% //パラメータの取得 String keyword = request.getParameter("keyword"); //ドライバーのロード Class.forName("com.mysql.jdbc.Driver"); //DBに接続 String url = "jdbc:mysql://localhost/java4z?useUnicode=true&characterEncoding=MS932"; String user = "root"; String pass = ""; Connection con = DriverManager.getConnection(url,user,pass); //SQL発行先ほど指定したConnection con を利用 Statement stmt = con.createStatement(); String sql = "select * from shop where name like '%" + keyword + "%' or author like '%" + keyword + "%' ; ResultSet rs = stmt.executeQuery(sql);%> jspとmysqlの連動したページを作っているのですが select count(*) from テーブル名;を使い 件数を表示(XX件目など)させたいのです さらに値段からXX円以上からXX円以下なども データから検索し表示させたいのですが String sql = "select * from shop where name like '%" + keyword + "%' or author like '%" + keyword + "%' ;の部分をどのように記述すればよいか 解かりません! どなたかお願いします☆()

    • ベストアンサー
    • MySQL
  • SQL文にて・・・

    質問があります。PostgreSQLです。 テーブル(test_tbl)があるとします。 テーブル構成は --------------------------- id ===== char(16) [英数文字格納] point ==== int2 add_date ==== timestamp --------------------------- このテーブルから idが2文字目から'di6ek68dh5ls7g'のレコードを取得したいと考えています。 レコード数がかなりおおいので パフォーマンスを重視したいのですが、 検索SQLがわかりません。 select * from test_tbl where id like '%di6ek68dh5ls7g'だとでると おもうのですが、 これ以上にパフォーマンスがあがる SQLがわかる方お願いいたします。

  • SQL : たしかに DELETE したの?

    ありがちな処理かと思いまして質問させていただきます。 SQLで DELETE を行う際、WHERE で絞り込んだ対象行がなくても、  「エラーは返ってこない」 ということですが、NOT FOUND判定はするのでしょうか。 ごく単純に、削除しようとしたデータが実際にあったのかを確認したいのです。 やろうとしている処理は、次のようなものです。 DELETE FROM a_tbl WHERE NOT EXISTS (SELECT row1 FROM b_tbl WHERE row1 = 'input_data' ) AND NOT EXISTS (SELECT row1 FROM c_tbl WHERE row1 = 'input_data' ); ようするに、他のテーブルに、すでにない行であることが前提で、 a_tbl から DELETE したことを確認したいのです。 Pro*C内で実行するのですが、一般に同じだと思います。 キホンのキかもしれませんが、よろしくお教えください。

  • AccessのSQLで、レコード数の取得方法を教えてください。

    すみませんが、教えてください。 AccessをADO+SQLで操作しています。 cnn.Open **** sql="SELECT hoge FROM tabeleHoge;" set rec=cnn.Execute(sql) で、recオブジェクトから、レコード数を取得する方法ってあるのでしょか? sql="SELECT COUNT(*) FROM tableHoge;" を使わずに、できれば、嬉しいのですが。 以上、よろしくお願いいたします。

  • 動的SQLのCOUNTのとり方

    動的SQLで、DBの件数を取得したいのですが、 うまく取得できず困っています。 教えてください! 以下の様に、記述しているのですが取り方間違っていますか? EXEC SQL EXECUTE statment INTO :CNTNUM; PREPEAした、statmentには SELECT COUNT(*) FROM テーブル名 where kbn = 3; と、ごくごく普通のSELECT COUNT文です。 cnt_numは、int型のホスト変数で宣言しています。 デバックしながら実行すると、cnt_numの値は初期化した時の 0のままです。実際取得した件数が0件なのかもと思い 初期化時に3を代入して実行したら、やはり値は3でした。 なので、件数が取得出来ていないようです。 オラクルエラーにもならず、次の処理へ流れていってしまいます。 知っている方、教えてください。

  • ACCESSのSQLの書き方

    ACCESSでのSQL文の書き方を教えてください。 テーブルtbl_Aとテーブルtbl_Bがあり, tbl_Aで得られた数値とtbl_Bで得られた数値を加えたものを結果として表示します。 どう書けばよろしいのでしょうか。どうしてもエラーになってしまいます。 イメージとしてはこんな感じです。 select (select ~~ from tbl_A where ~~)+(select ~~ from tbl_B where ~~) (もしoracleならば,「from dual」というのを最後に付けるんですが。)