MySQL / PHP Arama Verimlilik

3 Cevap php

Benim site için küçük bir arama oluşturmak için çalışıyorum. Ben tam metin dizini arama kullanarak denedim, ama çalışmak için asla olabilir. İşte ben geldim budur:

if(isset($_GET['search'])) {

$search = str_replace('-', ' ', $_GET['search']);
$result = array();

$titles = mysql_query("SELECT title FROM Entries WHERE title LIKE '%$search%'");
while($row = mysql_fetch_assoc($titles)) {
    $result[] = $row['title'];
}

$tags = mysql_query("SELECT title FROM Entries WHERE tags LIKE '%$search%'");
while($row = mysql_fetch_assoc($tags)) {
    $result[] = $row['title'];
}

$text = mysql_query("SELECT title FROM Entries WHERE entry LIKE '%$search%'");
while($row = mysql_fetch_assoc($text)) {
    $result[] = $row['title'];
}

$result = array_unique($result);
}

Yani temelde, bu DB tüm girişlerin tüm başlıkları, vücut-metin, ve etiketleri arar. Bu terbiyeli iyi çalışıyor, ama ben sadece ne kadar verimli olacağını merak ediyorum? Bu sadece çok küçük bir blog için olacaktır. Bu, ben sadece merak ediyorum ya da yolu bir daha verimli yapılabilir.

3 Cevap

LIKE '%pattern%' sorguları verimli yapmak için hiçbir yolu yok. Bir tam metin indeksleme çözüm kullanarak daha yavaş kez yüzlerce veya binlerce gerçekleştirir, bu joker sorguları kullanarak, veri nontrivial miktarda olsun.

You should look at the presentation I did for MySQL University: http://www.slideshare.net/billkarwin/practical-full-text-search-with-my-sql

İşte işe almak için nasıl:

  1. Önce masa MyISAM depolama motorunu kullandığından emin olun. MySQL FULLTEXT indeksler sadece MyISAM tablolarını desteklemez. (edit 11/1/2012: MySQL 5.6 InnoDB tablolar için FULLTEXT indeks türü tanıtıyor.)

    ALTER TABLE Entries ENGINE=MyISAM;
    
  2. Bir tam dizin oluşturun.

    CREATE FULLTEXT INDEX searchindex ON Entries(title, tags, entry);
    
  3. Arayın!

    $search = mysql_real_escape_string($search);
    $titles = mysql_query("SELECT title FROM Entries 
        WHERE MATCH(title, tags, entry) AGAINST('$search')");
    while($row = mysql_fetch_assoc($titles)) {
        $result[] = $row['title'];
    }
    

    Eğer MATCH fıkrasında isim sütunlar must Eğer tam metin dizini tanımında ilan gibi aynı sırayla aynı sütun olabilir unutmayın. Aksi takdirde çalışmaz.


Ben tam metin dizini arama kullanarak denedim, ama bu herhangi daha verimli yapılabilir, ben sadece merak ediyorum ... o iş için asla olabilir.

Bu tam olarak, demek gibi bir şeydir "Ben bu testereyi nasıl kullanılacağını çözemedim, ben testerenin yanı sıra bu işi nasıl yapabilirim. Bir çakı ile bu sekoya ağacı kesmeye karar verdi?"


Satır% 50'den fazla eşleşen sözcükleri ararken hakkında yorum ile ilgili.

MySQL manuel diyor this:

% 50 sınırlamasını aşmak için gereken kullanıcılar boolean arama modunu kullanabilirsiniz; bkz Section 11.8.2, “Boolean Full-Text Searches”.

Ve this:

The 50% threshold for natural language searches is determined by the particular weighting scheme chosen. To disable it, look for the following line in storage/myisam/ftdefs.h:

# GWS_IN_USE GWS_PROB tanımlamak

Bu o satırı değiştirin:

# GWS_IN_USE GWS_FREQ tanımlamak

Then recompile MySQL. There is no need to rebuild the indexes in this case.

Ayrıca, stopwords arıyor olabilir. Bunlar çok yaygın çünkü tam metin arama tarafından göz ardı edilir kelimelerdir. "" Ve benzeri gibi kelimeler. Bkz http://dev.mysql.com/doc/refman/5.1/en/fulltext-stopwords.html

MySQL tam metin arama işleri - Ben içine bakmak ve onu ayıklamak yerine bunu yapmak için çalışıyor olacaktır. 3 ayrı MySQL sorguları yapıyor yerde verimli yakın olmayacak.

Eğer verimli kadar OR aralarında olan bir sorguda LIKE ifadeleri ayrı olabilir emin olmak için denemek istiyorsanız.

Kullanma LIKE olan NOT tam metin.

Sen tam arama erişmek için ... WHERE MATCH(column) AGAINST('the query') kullanmanız gerekir.