• ベストアンサー

キーワード検索の方法

いつもお世話になっております。 以下のようなテーブル(news)があります。 cid(int)|nid(int)|news_date(date)|body(text) キーは cid と nid です。 約4000件のデータからキーワードの検索をするのに とても時間がかかってしまいます。 SQL文は以下のようにしております。 select * from news where news_date between '2008-03-03' and '2009-03-03' and nid='1' and (body regexp 'キーワード1' or body regexp 'キーワード2') order by news_date DESC どうしたら速度が早くなるのでしょうか? インデックスをはったりすればいいのでしょうか? よろしくご教授お願いいたします。 <環境> MySQL:4.1.22(utf-8)

  • MySQL
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • masa6272
  • ベストアンサー率66% (93/140)
回答No.2

基本的に、曖昧検索は、遅いです。 インデックスは役に立ちません。 こういう、検索にはRDBMSは向いていません。 ORで、結ばれているregexpを次のようにして、2つにまとめれば、2倍弱の速度向上はできるでしょうが。 body regexp 'キーワード1|キーワード2'

その他の回答 (1)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

>約4000件のデータからキーワードの検索をするのに >とても時間がかかってしまいます。 ホントに4000件(?)ならSQLのデータとしてはすくない部類ですね テキストタイプということですが、1データはどのくらいの容量なのでしょう? テキストだとインデックスもそれほど期待できないと思います。 本質的には文字を分かち書きして全文検索にするでしょうか・・・ もしくはキーワードを抽出して別テーブルで管理するとか。

wonder_dct
質問者

補足

yambejp さん、ご回答ありがとうございます。 > ホントに4000件(?)ならSQLのデータとしてはすくない部類ですね > テキストタイプということですが、1データはどのくらいの容量なのでしょう? はい。 4000件で、1データの容量はちょっと定かではありませんが 全体のデータ量は約8MBぐらいです。 詳しくご説明しないと原因の特定が難しいのは承知なのですが 想像でも結構ですので、何か他に遅くなる原因が考えられましたら 教えていただきたいです。 よろしくお願いいたします。

関連するQ&A

  • MySQLで期間指定でキーワード検索するには?

    PHPでMySQLを利用し開発を行っています。 検索ボックスにキーワードを入力して検索をしたいのですが、期間を指定して検索できるようにする方法が分かりません。 さらに1ページに五件ずつ表示するようにしています。 下記はキーワード検索として動いているプログラムです。 例は2つのフィールドから検索しています。 SELECT * FROM テーブル名 WHERE フィールド名1 LIKE '%$search%' OR フィールド名2 LIKE '%$search%' LIMIT 0, 5; これに BETWEEN 期間1 AND 期間2  を追加して完成させようと思っているのですが、 どうも上手くいかないので、どのように書けばよいか教えて下さい。 よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • checkbokとキーワード検索を組み合わせた検索

    PHP4とMySQL4.0.22を使っています。 チェックボックスとキーワードで検索結果を表示させたいと思い。 下記のようにプログラムを作成したのですが、うまく検索表示してくれません。 PHPもMySQLも初心者なため、あちこちの構文を寄せ集めたため、Parseもうまく通っていません。 どこをどういう風にすればうまくいくのか、教えていただけないでしょうか? よろしくお願いします。 ----------------------------以下PHPファイル----------- 検索フォーム 検索キーワード:<input type=text name=\"k\"value='$k' size=45 > チェックボックス <INPUT TYPE=\"CHECKBOX\" NAME=\"bumon[]\" value=\"01:河川・砂防及び海岸\">01:河川・砂防及び海岸 ・・ "; //データ検索結果の実行部分 if($sig=="kb"){ $wk ==""; if($wk<>""){ //チェックボックス $sql = "select * from tecris where"; $sql .= " ("; $i=0; foreach($_POST['bumon'] as $fr) { if ($i) { $sql .= " or "; } $sql .= "bumon = '$fr'; $i++; } $sql .= ") and "; //キーワード if($k<>""){ $xk = str_replace(" "," ",$k); $gk = explode(" ",$xk); $wk ="keyword like '%$gk[0]%'"; $i = 1; $n = count($gk) - 1; while ($i <= $n){ $wk = $wk . " and keyword like '%$gk[$i]%'"; $i++; } } //クエリの作成 $sql = $sql . $wk; };

    • 締切済み
    • PHP
  • REGEXPを使った検索文をスマートにできますか

    初心者ではございますが、質問失礼いたします。 下記のようなSQL文を使っています。 例文: SELECT table1.no, table1.titile, table1.date FROM table1 WHERE ( table1.title REGEXP "りんご" || table1.title REGEXP "みかん" || table1.title REGEXP "ばなな" || ......... AND date > '2013-11-11' ORDER BY table1.date DESC table1.titleから、各単語を含むタイトルを全て表示させるもので、 検索する単語は無制限に増える予定です。 現在の文でも結果など特に問題ないのですが、 コードが長くてこれでいいものかと思い探したところ特になかったため、 良い方法をご存知の方がいらっしゃったら・・・という望みで 質問の方させていただきました。 お時間のある際にでもお教えいただければと思います。 もし、上記に変わる表現がない場合は、無いとお教えいただければ助かります。 何卒宜しくお願い致します。

    • ベストアンサー
    • MySQL
  • php複数キーワード検索

    いつもお世話になっております。 php+MySQLにて検索機能を作成しています。 キーワードが1つの場合には以下のスクリプトで正常に動作していますが、全角あるいは半角のスペースによって複数キーワードを入れた場合にも検索が行われるようにしたいと思っています。 現在のスクリプト $word=$_POST["seek"]; $word=stripslashes($word); $con_word=mb_convert_encoding($word,"EUC-JP","auto"); //データベース接続がここに入ります $sql="SELECT words,name,id FROM profile WHERE words like '%$con_word%'"; ここで、スペースを" AND "に置き換えるために、 $word=preg_replace('/\s+/',' ',$word); $word=preg_replace('/ /',' AND ',$word); あるいは $word=mb_convert_kana($word,"as","EUC-JP"); $word=preg_replace('/ /',' AND ',$word); などを試してみたのですがうまく動作しません。 どなたか問題点を具体的にご指摘いただけないでしょうか。 よろしくお願いいたします。 *環境 php mysql レンタルサーバ(ロリポップ)

    • ベストアンサー
    • PHP
  • 文字の検索について

    「test」というデータベースの「shouhin」というフィールドに、次のようなレコードがあった場合、「PHP」というキーワードと「本」というキーワードの両方にマッチしたレコードを抽出したいのですが、自分で試した方法は、下記の2つの方法なのですが、この方法では、マッチさせるキーワードが3個の場合4個の場合を考えると式が複雑になってしまいます。 今やりたいことは、たとえば、googleでの検索のように、「PHP 本」と入力したら、PHPと本の両方のキーワードを含んだレコードを抽出したいのです。「PHP 本 楽しい」なら、この3つのキーワードを含んだレコードといった感じに。 検索したいキーワードを変数(たとえば、$keyword='PHP 本')にいれておいて、これを簡単に実現するsqlの記述の仕方はありますか? ご回答よろしくお願い致します。 ●「test」というデータベースの「shouhin」というフィールドに対して検索 ID |shouhin --+---------- 1 | PHPが書かれた本 2 | この本はPHPが書かれています 3 | 楽しいPHPの本 4 | HTMLの本 --+--------------------------- ●試してみた方法2種類 SELECT * FROM `test` WHERE shouhin REGEXP '(アジアン.*テーブル)|(テーブル.*アジアン)' SELECT * FROM `test` WHERE shouhin LIKE '%アジアン%' and shouhin_name LIKE '%テーブル%'

  • 特定のデータの前後を取得したい

    以下のようなテーブルがあり、 SELECT id , regist_date FROM table_name ORDER BY regist_date DESC; ↑このSQLで並べると↓以下になるとします。 id(int型)   regist_date(datetime型) 12      2017-03-30 08:05:03 95      2017-03-29 19:05:03 72      2017-03-28 12:05:03 15      2017-03-28 12:05:03 62      2017-03-27 15:05:03 94      2017-03-26 12:05:03 やりたい事はidが72というのが分かっており、 そのデータと前後のデータを取得したいです。 ※日付の部分が完全に重複するデータが存在する場合もあります。 ※idは重複しません。 ↓このデータがとりたいです。 95      2017-03-29 19:05:03 72      2017-03-28 12:05:03 15      2017-03-28 12:05:03 SELECT * FROM table_name WHERE id = 72 ORDER BY regist_date DESC; ここから先が分からなくなってしまいどなたかわかる方いらっしゃいますか?

    • ベストアンサー
    • MySQL
  • 難しいSQL

    別の掲示板に質問したのですが、難易度が高いのかしばらく回答が得られなかったのでこちらに質問してみます。(別の掲示板の方は質問を取り消しました。)ちょっと急いでいるのでどんなものでも構いません。SQLに詳しい方、ご教示お願い致します。環境は、MySQL5.1.33(MacOSX版)を使用しています。 以下のようなデータベースがあります。マスター系となるユーザテーブルと、それを参照するトランザクション系の買い物テーブルです。このデータベースから、「※連続して買い物をしたユーザをSELECTしたい」のですがそのようなことは可能でしょうか?可能であるとすると、どのようなSQLを書けばよろしいでしょうか? ※「連続して」とは、日付をまたがって、という意味です。 例)2009/06/12、2009/06/13 (1)ユーザテーブル mysql> desc user; userid, int(11), primary key username varchar(15) (2)買い物テーブル mysql> desc purchase; purchaseid, int(11), primary key userid int(11) purchaseid date 今、買い物テーブルに以下のようにデータがある場合 mysql> select * from purchase; 1, 3, 2004-01-02 6, 1, 2004-04-03 5, 2, 2008-04-05 4, 2, 2000-01-19 3, 5, 2004-01-01 2, 1, 2001-11-10 9, 5, 2003-12-31 8, 1, 2007-04-05 7, 3, 2004-01-03 mysql> select userid from ... とすると3, 5を抜き出すようにしたいです。(3は2004/01/02, 2004/01/03だから。5は2003/12/31, 2004/01/01だから。) このselect文の書き方を教えて頂きたいです。お手数をおかけしますがよろしくおねがいします。

  • SQLが走らない

    なぜかSQLが走りません。 エラーもでません。 カテゴリーリンクを押したら、そのカテゴリに書いた記事が表示されるようにしています。 $stmt = $pdo->query('SELECT * FROM ' . DATABASE_TABLE_ARTICLE . ' LEFT JOIN ' . DATABASE_TABLE_CATEGORY . ' USING (cid) WHERE cid = :cid ORDER BY date DESC'); $stmt->bindValue(':cid', $cid, PDO::PARAM_INT); if (!$stmt) { db_error($pdo->errorInfo()); } 1.$cidの値は取れています。 2.WHERE文をなくすと文が表示されます。 3.:cidに直接数字4とかを入れると大丈夫です。 4.cid = :cidのところがおかしいようです。 この記述どこか間違っているでしょうか? ほかの動いている部分のスクリプトをもってきているのですが・・・。

  • MySQLの日付型データをBetweenで抽出する方法

    MySQL で格納したデータを Perl を使ってブラウザに出力したいのです が、日付型で格納したデータを Between で範囲を指定して出力しても 条件通り出力できません。 Between 式が間違っているまでは把握しているのですが、修正方法が 分かりません。どなたか教えていただけませんか? # $form->param('combo1')は、2006 が格納されている $date1 = $form->param('combo1') . "/04/01"; $date2 = $form->param('combo1')++ . "/03/31"; # $date1 の値は、2006/04/01 # $date2 の値は、2007/03/31 $sql = "SELECT Itaku_Date FROM table WHERE "; $sql .= "Between " . $date1 . " And " . $date2;

  • MySQLのCHECK制約がうまくいきません。

    scoreカラムに1から100までの整数しか入らないようにするには どうしたらいいですか? MySQLのバージョンは、5.0.51 です。 以下の文は、なんのエラーもなく、INSERTされてしまいます。 CREATE TABLE scores (   score  INT NOT NULL,   CHECK ( score BETWEEN 1 AND 100 ) ) ENGINE = InnoDB; INSERT INTO scores (score) VALUES (1000); どう書けばいいのでしょうか? もしくは、MySQLのCHECK制約について詳しく書かれたページはないでしょうか?

    • ベストアンサー
    • MySQL