【问题标题】:MySQL help/suggestions on optimizing a query on large database关于优化大型数据库查询的 MySQL 帮助/建议
【发布时间】:2012-01-31 07:11:28
【问题描述】:

我有一个 MyISAM mysql 表:

CREATE TABLE IF NOT EXISTS `songs` (
  `rid` int(11) NOT NULL auto_increment,
  `aid` int(11) NOT NULL,
  `song_title` varchar(256) NOT NULL,
  `download_url` varchar(256) NOT NULL,
  PRIMARY KEY  (`rid`),
  UNIQUE KEY `download_url` (`download_url`),
  KEY `song_title` (`song_title`),
  FULLTEXT KEY `song_title_2` (`song_title`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1

它有大约 1400 万行。这是我第一次处理这么大的数据库,之前我并没有真正关心过优化。我一直在尝试各种方法来测试速度和准确性。

1) 全文

select song_title from songs 
where match (song_title) againt ('search term') limit 0, 50
-- This gives me very unreliable results but speed is good.

2) 喜欢

select song_title from songs 
where song_title LIKE '%search term%' limit 0, 50
-- Moderate matching results, speed is good when the query is 
-- easily able to fetch the first 50 results... but when i 
-- search for a term that does not exist then... here is the result..
-- MySQL returned an empty result set (i.e. zero rows). ( Query took 107.1371 sec )

3) 多个 LIKE

select song_title from songs 
where song_title like '%word_1%' and 
      song_title like '%word_2%' and 
      song_title like '%word_3%' and 
      song_title like '%word_N%' LIMIT 0, 50;
-- It takes about 0.2 seconds when the search terms are easily found.
-- Ran this exact above query just now to find the execution time when 
-- no results are found.
-- MySQL returned an empty result set (i.e. zero rows). ( Query took 30.8625 sec )

我正在寻找的是关于优化数据库/查询的速度和准确性方面的提示和建议。

我不能使用像 sphinx 这样的其他搜索引擎,因为我没有网站根目录之外的访问权限,也不能要求处理服务器的人进行设置。

【问题讨论】:

  • P.S.对这么多的编辑感到抱歉..这里的第一个问题,只是学习如何缩进代码块..但在一行左侧放置 4 个空格后,我似乎无法正确理解..
  • 缩进代码块 - 突出显示并按 ctrl+k
  • 你的服务器端语言是什么?

标签: mysql full-text-search query-optimization large-data


【解决方案1】:

由于用于该类型指数。它将使用索引进行前缀搜索,例如 LIKE 'word%'。请注意,MySQL 全文索引根本不涵盖 LIKE 查询。 MyISAM 全文索引涵盖的唯一查询是 MATCH ... AGAINST ...

假设您的数据集大小确实需要外部搜索引擎,尤其是当您计划增加搜索的数据量时。

我没有关于您的托管环境的详细信息,但如果您可以通过 SSH 访问托管服务器,我相信您可以以非特权用户身份安装和运行 Sphinx。使用 ./configure 脚本将位置前缀设置为您的主目录(但请确保它不能从网络访问),如下所示:

./configure --prefix=/path/to/your/home

然后执行

make && make install

然后按照http://astellar.com/2011/12/replacing-mysql-full-text-search-with-sphinx/ 中的描述创建 sphinx 配置,最后通过从命令行运行 searchd 来启动守护进程:

/path/to/your/home/bin/searchd

希望对你有帮助。

【讨论】:

    【解决方案2】:

    使用 like '%text%' 的查询不使用索引。 如果您正在寻找良好的性能,请使用全文版本,即使它不会返回准确的结果。 如果可以使用命令explain select ...查看查询中使用了哪些索引。

    您可以在此处查看更多信息:http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

    【讨论】:

    • 哦,差点忘记解释了.. 已经读过但从未尝试过.. 可以通过查看查询现在的实际工作方式来学习一些东西.. 好的..
    • 刚刚尝试了类似搜索,它确实使用了 song_title 索引。猜你的意思是它没有使用全文索引 song_title_2
    • @PrathameshGharat 你能提供explain 结果吗,因为LIKE '%word%' 不应该使用索引,它可以在explainpossible keys 列中,但不在key 列中。
    • @piotrekkr: SELECT song_title WHERE song_title LIKE '%word%'song_title 上使用索引(索引具有查询的所有字段 - 覆盖索引,因此 mysql 扫描索引,因为它比表扫描更快)。该索引也将用于SELECT song_title FROM table1
    • @a1ex07 在 mysql 5.1 的手册中,他们写道:以下 SELECT 语句不使用索引:SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%'; 不了解 5.5,因为在 5.5 中找不到关于索引和LIKE 的任何信息手册。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2011-08-05
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多