2

私は PDO の準備を作成していますが、より高速に実行できるように作成する別の良い方法があるかどうかを知りたいです。コードは次のとおりです。

function comp_post_code($cat, $comp_post_code){
            global $DBH;
            $STH = $DBH->prepare("SELECT * from uk_data where 
                                    cat10 like :comp_post_code  AND (
                                    cat1 like :cat OR
                                    cat2 like :cat OR
                                    cat3 like :cat OR
                                    cat4 like :cat OR
                                    cat5 like :cat OR
                                    cat6 like :cat OR
                                    cat7 like :cat 

                                    )") ;
            $STH->bindValue(':cat', "%$cat%", PDO::PARAM_STR);
            $STH->bindValue(':comp_post_code', "$comp_post_code%", PDO::PARAM_STR);
            $STH->execute();
            $STH->setFetchMode(PDO::FETCH_ASSOC);
            return $STH;
            $DBH = Null;
            }

テーブルから完全なデータが必要なので、Select を使用しています。* ....どうも

編集:- cat10 は郵便番号、cat 1 から cat7 はカテゴリです。特定の郵便番号でカテゴリを検索する必要があります。

テーブル形式は次のとおりです。

CREATE TABLE IF NOT EXISTS `uk_data` (
  `slno` int(10) NOT NULL AUTO_INCREMENT,
  `comp_name` varchar(150) DEFAULT NULL,
  `comp_no` varchar(50) DEFAULT NULL,
  `comp_street` varchar(100) DEFAULT NULL,
  `comp_area` varchar(100) DEFAULT NULL,
  `comp_post_code` varchar(15) DEFAULT NULL,
  `comp_phone` varchar(100) DEFAULT NULL,
  `comp_phone1` varchar(100) DEFAULT NULL,
  `cat1` varchar(100) DEFAULT NULL,
  `cat2` varchar(100) DEFAULT NULL,
  `cat3` varchar(100) DEFAULT NULL,
  `cat4` varchar(100) DEFAULT NULL,
  `cat5` varchar(100) DEFAULT NULL,
  `cat6` varchar(100) DEFAULT NULL,
  `cat7` varchar(100) DEFAULT NULL,
  `cat8` decimal(9,6) DEFAULT NULL,
  `cat9` decimal(9,6) DEFAULT NULL,
  `cat10` varchar(15) DEFAULT NULL,
  PRIMARY KEY (`slno`),
  UNIQUE KEY `Phone` (`comp_phone`),
  KEY `cat10` (`cat10`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=74504 ;

私が使用している出力:

$uk_data_radious = comp_post_code($q,$pc_o);
            while (($row = $uk_data_radious->fetch()) !== false) {
            $comp_name[] = $row['comp_name'];
            $comp_phone[] = $row['comp_phone'];
            $comp_phone1[] = $row['comp_phone1'];
            $post_code[] = $row['cat10'];
            $post_code1[] = $row['comp_post_code'];
            $comp_no[] = $row['comp_no'];
            $comp_street[] = $row['comp_street'];
            $comp_area[] = $row['comp_area'];
            $cat1[] =  $row['cat1'];
            $cat2[] =  $row['cat2'];
            $cat3[] =  $row['cat3'];
            $cat4[] =  $row['cat4'];
            $cat5[] =  $row['cat5'];
            $cat6[] =  $row['cat6'];
            $cat7[] =  $row['cat7'];
            $distance_m[] = distance($Latitude[0],$Longitude[0],$row['cat8'],$row['cat9'],"M");
            }
4

1 に答える 1

2

全文検索は、内部のどこでも検索するための長い文字列でより適切に機能します。ただし、特別なインデックスを作成し、クエリを変更する必要があります (InnoDB テーブルとは互換性がありません)。

これはかなりの作業です。ただし、likeクエリが非常に遅い場合は、FTI (全文インデックス) が高速な代替手段になります。

--

likeクエリを保持すると、できることはあまりありません-もちろん、列内でデータを整理する方法を変更しない限り-つまり、likeを回避するために。

likeクエリを何らかの方法で最適化するには、すべての cat を 1 つの列にマージ (つまり、新しい列catxを追加) し、 cat 、 likeでは発生しない特別な文字で区切って、: like」を 1 つだけ実行します (少しスピードアップするはずです)。例えば

cat1: alpha
cat2: beta
cat3: gamma
...

与える

catx is :alpha:beta:gamma:

catxで同様のことを行います

catx like :cat
  • 特定のを検索するには、「:mycat:」を検索します
  • 単語で始まるcatの一部を検索するには、「:start」を検索するか、
  • 末尾の単語を検索するには、「end:」を検索します。

like検索アルゴリズムは、短い文字列に対して複数回実行するよりも、長い文字列に対してより効率的です。検索文字列が 3 文字を超える場合、MySQL は非常に効率的なTurbo Boyer-Moore アルゴリズムを使用します。

ただし、警告する必要があります。この戦略にはいくつかの制約があります。

  • cat内に表示されるべきではない特別な区切り文字
  • cat[1-7]への更新にはcatxの調整が必要です。そのため、が大幅に変更される可能性がある場合、これは適切な解決策ではない可能性があります。
  • このソリューションは通常、よく知られているデータ (識別子など) に対して機能します。この形式はめったに変更されません。

経験的に、この戦略で 25% 以上の利益を期待できるとは思いません。

于 2013-02-05T17:31:19.090 に答える