Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.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数据库挂起的简单Select语句_Sql_Mysql_Indexing - Fatal编程技术网

MySQL数据库挂起的简单Select语句

MySQL数据库挂起的简单Select语句,sql,mysql,indexing,Sql,Mysql,Indexing,我在一个非常大的表上有一个非常简单的sql select语句,这是非规范化的。(根本不是我的设计,我只是试图优化,同时试图说服业主重新设计) 基本上,这种说法是这样的: SELECT FirstName, LastName, FullName, State FROM Activity WHERE (FirstName=@name OR LastName=@name OR FullName=@name) AND State=@state; 现在,FirstName、LastName、FullNa

我在一个非常大的表上有一个非常简单的sql select语句,这是非规范化的。(根本不是我的设计,我只是试图优化,同时试图说服业主重新设计)

基本上,这种说法是这样的:

SELECT FirstName, LastName, FullName, State
FROM Activity
WHERE (FirstName=@name OR LastName=@name OR FullName=@name)
AND State=@state;
现在,FirstName、LastName、FullName和State都作为btree索引,但没有前缀-整个列都被索引。“状态”列是两个字母的状态代码

我发现的是:

  • 当@name='John Smith'和@state='%时,搜索速度非常快,并立即生成结果
  • 当@name='John Smith'和@state='FL'时,搜索需要5分钟(通常这意味着web服务超时…)
  • 当我删除FirstName和LastName的比较,并且只使用FullName和State时,上述两种情况都会很快起作用
  • 当我替换FirstName、LastName、FullName和State搜索,但在每次搜索中使用LIKE时,@name='John Smith%'和@State='%'的搜索速度很快,而@name='John Smith%'和@State='FL'的搜索速度很慢
  • 当我搜索“John Sm%”和@state='FL'时,搜索会立即找到结果
  • 当我搜索“John Smi%”和@state='FL'时,搜索需要5分钟
  • 现在,重申一下——表没有标准化。John Smith和许多其他用户一样出现了很多次,因为没有对某种形式的users/people表的引用。我不确定单个用户可能出现多少次,但表本身有9000万条记录。再说一次,不是我的设计

    我想知道的是——尽管这种设计存在很多问题,但是什么导致了这个特定的问题

    我的猜测是索引树太大了,遍历它们需要很长时间。(名字、姓氏、全名)

    无论如何,我感谢任何人在这方面的帮助。就像我说的,我正在努力说服他们重新设计,但与此同时,如果有人能帮我弄清楚到底是什么问题,那就太棒了

    更新

    根据要求,以下是运行解释后的详细信息:

    id: 1, select type: 'SIMPLE', table: 'activity', type: 'ref', possible keys: 'IDX_LastName,IDX_FirstName,IDX_FullName,IDX_State', key: 'IDX_State', key_len: '3', ref: 'const', rows: 7227364, extra: 'Using where'
    

    只是猜测而没有看到您的执行计划,但是您可以尝试创建复合索引

    (FirstName, State)
    (LastName, State)
    (FullName, State)
    
    甚至是一个单一的复合索引:

    (State, FirstName, LastName, FullName)
    

    我想你需要花点时间解释一下
    。彼得·朗(Peter Lang)可能是对的,你需要一些复杂的索引,但解释将显示像这样的任何变化所产生的影响要比反复试验好得多


    哦,在您试图分析的任何select语句中使用
    SQL\u NO\u CACHE
    ,以防止查询缓存更改您的结果(只需在select之后添加它)

    我们需要知道表是如何定义的,以便为我们提供

    show create table Activity 显示创建表活动 会有帮助的

    从它的声音,有一些关于国家列-它是索引

    另一个好工具是EXPLAIN命令

    使用

    说明 挑选 名,姓,全名,州 从活动 (名字是约翰·史密斯) 或者姓“约翰·史密斯” 或全名(约翰·史密斯) 和State='FL';
    并将结果与查询的其他变体的解释输出进行比较。

    建议您使用解释查看查询计划。将这些查询的解释结果添加到您的问题中会非常有用。指数结构还不是100%清楚。还请包括9000万条记录的
    SHOW CREATE TABLE Activity\G
    的输出,如果像您所说的那样,每一列都有大量点击,那么您的时间很可能会花费在一次又一次地合并所有这些结果上,就像其他人所说的,“解释是您的朋友” EXPLAIN SELECT FirstName, LastName, FullName, State FROM Activity Where (FirstName='John Smith' OR LastName='John Smith' OR FullName='John Smith') AND State='FL';