1

データベースとしてmysqlを使用して、phpでWebサイトの製品検索システムを作成しています。

現在、10 万を超える製品を検索しています。私たちの要件は強度が低いため、Sphinx や Lucene の代わりに、MySQL の組み込みの全文機能 (Match and Against) を使用することを考えました。

当分の間、MySQL に組み込まれている全文検索機能を使用しますが、誰かがこの全文検索クエリを最適化して効率を高め、オーバーヘッドを少なくするのを手伝ってくれませんか。

SOで誰かが私に提案したように、フルテキスト構文を正しい方法で使用していない可能性があります。

テーブル構造の作成

-- Create Table SQL for Product --
DROP TABLE IF EXISTS `ps_search__p`;
CREATE TABLE IF NOT EXISTS `ps_search__p` (
  `id` int(10) unsigned NOT NULL,
  `code` varchar(100) NOT NULL,
  `type` varchar(100) DEFAULT NULL,
  `name` text,
  `keywords` text,
  `material` text,
  `material_def_id` int(11) unsigned DEFAULT NULL,
  `s_type` text,
  `s_fabric` text,
  `price` decimal(20,6) unsigned DEFAULT NULL,
  `build_type` varchar(12) NOT NULL,
  `genre` varchar(12) NOT NULL DEFAULT 'p',
  `categories` text,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `code` (`code`,`type`,`name`,`keywords`,`material`,`s_type`,`s_fabric`,`categories`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


-- Create SQL Table for S table --
DROP TABLE IF EXISTS `ps_search__s`;
CREATE TABLE IF NOT EXISTS `ps_search__s` (
  `id` int(20) unsigned NOT NULL,
  `s_id` varchar(100) NOT NULL,
  `type` varchar(100) NOT NULL,
  `fabric` varchar(100) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `price` decimal(20,6) unsigned DEFAULT NULL,
  `genre` varchar(12) NOT NULL DEFAULT 's',
  `categories` text,
  PRIMARY KEY (`id`),
  FULLTEXT KEY `s_id` (`s_id`,`type`,`fabric`,`name`,`categories`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

全文検索クエリ

SELECT SQL_CALC_FOUND_ROWS * FROM (
    ( SELECT 
        `id`, `code`, `name`, `material`,`material_def_id`, `s_type`, `s_fabric`, `price`, `genre`, `categories`,
        MATCH (`code`,`type`,`name`,`keywords`,`material`,`s_type`,`s_fabric`,`categories`)
        AGAINST ('+cotton*' IN BOOLEAN MODE) AS `relevance`
    FROM `ps_search__p`
    WHERE
        ( MATCH (`code`,`type`,`name`,`keywords`,`material`,`s_type`,`s_fabric`,`categories`)
        AGAINST ('+cotton*' IN BOOLEAN MODE))
        AND `s_type` REGEXP '.*'
        AND `s_fabric` REGEXP '.*'
        AND `material` REGEXP '.*'
        AND `price` REGEXP '.*'
        AND `categories` REGEXP '.*'
        )
UNION ALL
    ( SELECT
        `id`, `s_id`, `name`, NULL AS `material`, NULL AS `material_def_id`, `type`, `fabric`, `price`, `genre`, `categories`,
        MATCH (`s_id`,`type`,`fabric`,`name`,`categories`)
        AGAINST ('+cotton*' IN BOOLEAN MODE) AS `relevance`
    FROM `ps_search__s`
    WHERE
        ( MATCH (`s_id`,`type`,`fabric`,`name`,`categories`)
        AGAINST ('+cotton*' IN BOOLEAN MODE))
        AND `type` REGEXP '.*'
        AND `fabric` REGEXP '.*'
        AND `price` REGEXP '.*'
        AND IFNULL(`categories`, '') REGEXP '.*' )
) AS `tblsearch`
ORDER BY `relevance` DESC
LIMIT 0, 36

そして、クエリ数を取得するには

SELECT FOUND_ROWS() 'recordsnum';

少しでも助けていただければ幸いです。

4

1 に答える 1

1

すべてのテストREGEXP '.*'を に置き換えますIS NOT NULL

フルテキスト インデックスを活用し、次のようなテストを置き換えfabric REGEXP 'Cotton|Nylon'ますMATCH(fabric) AGAINST ("+Cotton" IN BOOLEAN MODE) OR MATCH(fabric) AGAINST ("+Nylon" IN BOOLEAN MODE)

データベースを正規化します。列に非スカラー値 (CSV データなど) を含めないでください。代わりに、新しいテーブルで一対多の関係を確立する必要があります。

于 2013-06-24T17:27:27.283 に答える