Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL,需要一些关于我的匹配查询的性能建议吗_Sql_Database_Mysql - Fatal编程技术网

MySQL,需要一些关于我的匹配查询的性能建议吗

MySQL,需要一些关于我的匹配查询的性能建议吗,sql,database,mysql,Sql,Database,Mysql,我需要一些性能改进指导,我的查询需要几秒钟才能运行,这会导致服务器出现问题。此查询在我的网站上最常见的页面上运行。我认为可能需要彻底反思 ~z~编辑~ 此查询生成一个记录列表,其关键字与所查询程序(记录)的关键字匹配。我的网站是一个软件下载目录。这个列表在程序列表页面上用于显示其他类似的程序。PadID是数据库中程序记录的主键 ~z~编辑~ 这是我的问题 select match_keywords.PadID, count(match_keywords.Word) as matching_wo

我需要一些性能改进指导,我的查询需要几秒钟才能运行,这会导致服务器出现问题。此查询在我的网站上最常见的页面上运行。我认为可能需要彻底反思

~z~编辑~ 此查询生成一个记录列表,其关键字与所查询程序(记录)的关键字匹配。我的网站是一个软件下载目录。这个列表在程序列表页面上用于显示其他类似的程序。PadID是数据库中程序记录的主键

~z~编辑~

这是我的问题

 select match_keywords.PadID, count(match_keywords.Word) as matching_words 
 from keywords current_program_keywords 
 inner join keywords match_keywords on
       match_keywords.Word=current_program_keywords.Word 
 where match_keywords.Word IS NOT NULL 
 and current_program_keywords.PadID=44243 
 group by match_keywords.PadID 
 order by matching_words DESC 
 LIMIT 0,11;
下面是问题的解释。

这里有一些示例数据,但是我怀疑您是否能够在没有更多数据的情况下看到任何性能调整的效果,如果您愿意,我可以提供这些数据

 CREATE TABLE IF NOT EXISTS `keywords` (
   `Word` varchar(20) NOT NULL,
   `PadID` bigint(20) NOT NULL,
   `LetterIdx` varchar(1) NOT NULL,
   KEY `Word` (`Word`),
   KEY `LetterIdx` (`LetterIdx`),
   KEY `PadID_2` (`PadID`,`Word`)
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

 INSERT INTO `keywords` (`Word`, `PadID`, `LetterIdx`) VALUES
 ('tv', 44243, 'T'),
 ('satellite tv', 44243, 'S'),
 ('satellite tv to pc', 44243, 'S'),
 ('satellite', 44243, 'S'),
 ('your', 44243, 'X'),
 ('computer', 44243, 'C'),
 ('pc', 44243, 'P'),
 ('soccer on your pc', 44243, 'S'),
 ('sports on your pc', 44243, 'S'),
 ('television', 44243, 'T');
我已经尝试添加索引,但这没有多大区别

 ALTER TABLE `keywords` ADD INDEX ( `PadID` ) 

尝试这种方法,不确定是否有帮助,但至少是不同的:

select PadID, count(Word) as matching_words
from keywords k
where Word in (
  select Word 
  from keywords
  where PadID=44243 )
group by PadID 
order by matching_words DESC 
LIMIT 0,11

无论如何,你想完成的工作很繁重,而且充满了字符串比较,也许导出关键字并在关键字表中只存储数字ID可以减少时间。

如果我理解正确,你可能会发现这很有帮助。该解决方案利用了innodb的集群主键索引(http://pastie.org/1195127)

编辑:以下是一些可能会引起兴趣的链接:

编辑:根据请求添加了char_idx功能

alter table keywords add column char_idx char(1) null after name;

update keywords set char_idx = upper(substring(name,1,1));

select * from keywords;

explain
select
 p.*
from
 programmes p
inner join
(
 select distinct
  pk.prog_id
 from
  programme_keywords pk
 inner join
 (
  select keyword_id from keywords where char_idx = 'P' -- just change the driver query
 ) keywords_starting_with
 on pk.keyword_id = keywords_starting_with.keyword_id
) matches 
on matches.prog_id = p.prog_id
order by
 p.prog_id;

好的,在查看了您的数据库之后,我认为查询没有太多的改进空间,事实上,在我的测试服务器上,在Word上使用索引只需要大约0.15秒就可以完成,如果没有索引,速度几乎要慢4倍

无论如何,我认为在数据库结构f00中实现更改,我已经告诉过您,这将提高响应时间

同时删除索引
PadID_2
,因为它现在是无效的,它只会减慢您的写入速度。 您应该做的是,但清理数据库需要避免重复的关键字prodId对,首先删除当前数据库中所有重复的关键字prodId对(在我的测试中约为90k,占数据库的3/4),这将减少查询时间并给出有意义的结果。如果您要求一个progId包含关键字ABC,该关键字与progdID2重复,那么progID2将位于其他具有相同ABC关键字但未重复的progId的顶部。在我的测试中,我看到一个progId与我查询的同一progId有多个匹配项。
从数据库中删除重复项后,您需要更改应用程序以避免将来再次出现此问题,并且为了安全起见,您可以向Word+ProgID添加主键(或唯一激活的索引)。

哇,这花了11秒,谢谢你的尝试,虽然我真的不确定还有什么可以存储为数字id?哈哈,至少我试过了,我说的是制作一个只有关键字和关键字id的关键字表,然后将当前关键字表重命名为hasKeywords或类似的东西,具有关键字id和程序id,这将减少数据库大小(因为关键字字符串不会被复制)也有助于字符串比较。无论如何,如果你想向frisco82@gmail.com发送更大的数据集,我会再试一次。哇,这比我想要的要激烈一点。没有什么激烈的地方-重要的部分是基于数字的程序关键字聚集主键索引(关键字_id,prog_id)。如果需要,您可以随时在自己的表上创建一个二级复合索引,但MyIsam的性能不如innodb,尤其是在负载下—请阅读:)我认为我的数据库是InnoDb,它位于phpmyadmin表列表的底部。我必须将我的程序表更改为InnoDb吗?同时,该过程何时使用,每天一次还是每次我需要创建类似程序的列表时。谢谢当前我表中的padid是
padid
bigint(20)NOT NULL auto_increment,medium int会有所不同吗?此外,这将留给我一些其他修复程序,它们依赖于关键字表…从pad中选择padid,其中关键字“%$search%”和RemovemeDate='2001-01-01 00:00:00'按VersionAddDate DESC排序;----选择*,计数(Word)作为
关键字
中的字数,其中
LetterIdx
='“$LetterCat.”按单词顺序分组;---我在这里需要做什么?
alter table keywords add column char_idx char(1) null after name;

update keywords set char_idx = upper(substring(name,1,1));

select * from keywords;

explain
select
 p.*
from
 programmes p
inner join
(
 select distinct
  pk.prog_id
 from
  programme_keywords pk
 inner join
 (
  select keyword_id from keywords where char_idx = 'P' -- just change the driver query
 ) keywords_starting_with
 on pk.keyword_id = keywords_starting_with.keyword_id
) matches 
on matches.prog_id = p.prog_id
order by
 p.prog_id;