1

LIKE 関数を使用するだけでなく、より複雑な検索機能を構築しようとするのはこれが初めてです。この検索から返された結果はほぼ完璧ですが、実行速度が非常に遅いです。スピードアップのためにコードに関して改善できることはありますか、またはデータベースで確認する必要があることはありますか? または、より多くのサーバーパワーを検討する必要がありますか?

ありとあらゆる助けに感謝します。それは大歓迎です!

function new_live_search($q){

    $title_score = 5;
    $tags_score = 10;
    $upvote_score = 1;

    $subdomain = $this->config->item('subdomain_name');

    $query = "SELECT DISTINCT results.*,
                ( 
                    ".$title_score."*(MATCH(title) AGAINST('$q' IN BOOLEAN MODE)) + 
                    ".$tags_score."*(MATCH(tags.name) AGAINST('$q' IN BOOLEAN MODE)) + 
                    ".$upvote_score."*usefulness
                ) AS score
                FROM results
                LEFT JOIN tags ON results.id = tags.result_id
                WHERE (scope = 'all' OR scope = '$subdomain') 
                        AND (published = 1)";

    $query .=  "
        HAVING score - usefulness > 0 
        ORDER BY score DESC, title";

    $query = $this->db->query($query);

    $results = array();


    foreach ($query->result() as $row){
        $results[] = $row;
    }

    return $results;

}
4

2 に答える 2

1

MySQLのドキュメントから

残念ながら、フルテキスト フィールドと通常の (つまり整数) フィールドを 1 つのインデックスに結合することはできません。クエリごとに 1 つのインデックスしか使用できないため、それが問題のようです

テーブル レイアウト:

id(integer primary key)|content(text fulltext indexed)|status(integer key)

次のクエリを実行すると、MySQL は 1 つのインデックスのみを使用することに注意してください。フルテキストまたはステータスのいずれか (インターンの統計による)。

クエリ 1:

SELECT * FROM table WHERE MATCH(content) AGAINST('searchQuery') AND status = 1

ただし、1 つのクエリで両方のインデックスを使用することは可能です。ID、ステータスのペアに新しいインデックスが必要になり、結合を使用します。したがって、MySQL はテーブルごとに 1 つのインデックスを使用できます。

クエリ 2:

SELECT t1.* FROM table t1
LEFT JOIN table t2 ON(t1.id=t2.id)
WHERE MATCH(t1.content) AGAINST('searchQuery') AND status=1

クエリ 2 は、少なくとも私の場合、クエリ 1 よりも大幅に高速に実行されます:) オーバーヘッドに注意してください: 各行の ID と、ID で始まる必要なフィールドにまたがるキーが必要になります。MySQL ドキュメントの全文検索を

参照してください。

于 2012-12-21T11:12:55.023 に答える
0

クエリを見ると、クエリの全文部分は実際には検索を制限していません。次のようなものを使用すると、パフォーマンスが少し向上するはずです。

SELECT DISTINCT results.*, (
    $title_score * (MATCH(title) AGAINST('$q' IN BOOLEAN MODE)) + 
    $tags_score * (MATCH(tags.name) AGAINST('$q' IN BOOLEAN MODE)) + 
    $upvote_score * usefulness
) AS score
FROM results
LEFT JOIN tags ON results.id = tags.result_id
WHERE (scope = 'all' OR scope = '$subdomain') 
    AND (published = 1)
    AND (
        (MATCH(title) AGAINST('$q' IN BOOLEAN MODE)) OR
        (MATCH(tags.name) AGAINST('$q' IN BOOLEAN MODE)))
HAVING score - usefulness > 0 
ORDER BY score DESC, title
于 2012-12-21T12:20:15.657 に答える