如何改进我的选择查询以使其更快?

时间:2016-11-22 10:14:30

标签: mysql

我有一张员工表(大约450万),其中包含名为job_titledomain的列。

我希望能够创建和运行动态查询,以根据作业标题选择特定的员工,并且其域名也在所提供的域数组中。

它是如何工作的,前端的用户最终会有大量的域名(200到10,000+之间),然后输入两个东西:

  1. 他们想要哪些职位包括
  2. 他们想要哪些职位排除
  3. 然后我们构建一个最终看起来像这样的查询:

    SELECT employee_id
    FROM employee
    WHERE (
            domain LIKE '%shetlandfoods.co.uk' 
            OR domain LIKE '%example1.co.uk' 
            OR domain LIKE '%example2.co.uk'
    
            -- About 50 additional domains in this list
    
            OR domain LIKE '%example50.co.uk'
        ) 
        AND (job_title LIKE '%Manager%' OR job_title LIKE '%Director%') 
        AND (job_title NOT LIKE '%Assistant%')
    

    请注意,域名列表非常长,可能包含数千个域名(!)

    现在,像这样的查询大约需要230秒,而且只有大约180个域!想象一下,使用成千上万;它需要永远。

    我想知道是否有任何方法可以优化/更改此查询以使其运行速度更快一些?或者我可以对数据库做些什么?

3 个答案:

答案 0 :(得分:3)

以下是两个可供选择的选项(@paul在评论中提到的第二个选项)。

其中一个原因是您可以预先处理domain列中的数据,使其仅具有确切的域名,而不包含任何其他内容。这是一个众所周知的问题,并且在Java或JavaScript中相对容易处理。如果这样做了,那么您可以在domain列上添加索引并使用WHERE子句,如下所示:

WHERE domain IN ('shetlandfoods.co.uk',
                 'alac.shetland.co.uk',
                 'malakofflimited.co.uk',
                 ...)

另一种选择可能是将域的反向与原始WHERE子句中的术语相反,例如。

WHERE REVERSE(domain) LIKE 'ku.oc.sdoofdnaltehs%' OR
      REVERSE(domain) LIKE 'ku.oc.dnaltehs.cala%' OR
      REVERSE(domain) LIKE 'ku.oc.detimilffokalam%' OR
      ...

您甚至可以从应用程序/ UI层存储domain的反向,这样您就不必强制MySQL计算WHERE子句中每个术语的反向。

我可能倾向于第一个选项,假设你有足够的带宽在击中MySQL之前提取域名。

答案 1 :(得分:0)

对于这种情况,您可以按如下方式创建临时表:

CREATE TEMPORARY TABLE domain_values (
  domain_value VARCHAR(100)
);

然后将所有域名插入:

INSERT INTO domain_values  VALUES ('%shetlandfoods.co.uk'), ('%shopshetlandtoday.co.uk'), ........;

然后选择:

SELECT e.employee_id FROM employee e JOIN domain_values d ON (e.domain LIKE d.domain_value)  AND
     (e.job_title LIKE '%Manager%' OR e.job_title LIKE '%Director%') AND (e.job_title NOT LIKE '%Assistant%');

答案 2 :(得分:0)

将文字翻转为

cellFullname.textLabel?.text = arr[index.row]

是一个选项,你可以尝试另一个,你也可以尝试这个

WHERE REVERSE(domain) LIKE 'ku.oc.sdoofdnaltehs%' OR REVERSE(domain) LIKE 'ku.oc.dnaltehs.cala%' OR REVERSE(domain) LIKE 'ku.oc.detimilffokalam%'...

这比SELECT employee_id FROM employee WHERE INSTR( domain,'shetlandfoods.co.uk' ) > 0