如何使我的SELECT查询更有效?

时间:2015-11-27 15:02:08

标签: mysql sql performance select

我是SQL的初学者,我对这个请求有些麻烦,因为效率太低而无法执行。在这里,它只是加载了几个小时(!)

SELECT my_db_client_total.email as EMAIL_TOTAL, 
    my_db_client_total.name, my_db_client_total.country 
    FROM my_db_client_total, my_db_client_pro
      WHERE (my_db_client_total.email<>'' ) 
    AND (my_db_client_total.country = '120') 
    AND (my_db_client_total.email IN (SELECT my_db_client_pro.email 
    FROM my_db_client_pro));

我的表格以这种方式组织:

Table 1 :        Table 2 :
   email         email
   name          name
   country       country

请求它测试我的数据库的目的,并处理我想从email name中选择countryTable 1table1.email的进一步请求{1}}不在table2

抱歉我的英语不好,而且就我的水平而言,正如我之前所说,我是初学者并且是自学成才。

如果有人能帮助我或至少启发我,我会非常感谢你的时间。

编辑:我没有准确知道,但我正在使用一张有2万多行的表格。

5 个答案:

答案 0 :(得分:1)

你的问题表明你正在使用MySQL,所以这会给你一个内部(记录必须存在于两个表中)加入。

SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country 
FROM my_db_client_total inner join my_db_client_pro on my_db_client_pro.email = my_db_client_total.email
WHERE (my_db_client_total.email<>'' ) AND (my_db_client_total.country = '120');

要选择另一个表中不存在的行,请执行以下操作:

SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country 
FROM my_db_client_total LEFT OUTER JOIN my_db_client_pro on my_db_client_pro.email = my_db_client_total.email
WHERE (my_db_client_total.email<>'' ) AND (my_db_client_total.country = '120') AND my_db_client_pro.email IS NULL;

答案 1 :(得分:1)

这是您的查询(使用表别名修复了一下):

SELECT ct.email as EMAIL_TOTAL, ct.name, ct.country
FROM my_db_client_total ct 
WHERE (ct.email <> '' ) AND
      (ct.country = 120) AND 
      (ct.email IN (SELECT my_db_client_pro.email FROM my_db_client_pro));

(我假设120实际上是一个整数。)

在旧版本的MySQL中,existsin更有效,因此将查询重写为:

SELECT ct.email as EMAIL_TOTAL, ct.name, ct.country
FROM my_db_client_total ct 
WHERE (ct.email <> '' ) AND
      (ct.country = 120) AND 
      EXISTS (SELECT 1 FROM my_db_client_pro cp WHERE cp.email = ct.email);

接下来,考虑索引。对于此查询,好的索引是:

create index idx_my_db_client_total_2 on my_db_client_total(country, email, name);

create index idx_my_db_client_pro_email on my_db_client_pro(email);

答案 2 :(得分:0)

SELECT my_db_client_total.email as EMAIL_TOTAL, 
  my_db_client_total.name, my_db_client_total.country 
FROM 
  my_db_client_total, 
WHERE (my_db_client_total.email <> '') 
AND (my_db_client_total.country = '120') 
AND (my_db_client_total.email not IN (SELECT my_db_client_pro.email
  FROM my_db_client_pro));

基本上从表中获取所有数据以及获取电子邮件地址的条件不在表2中

答案 3 :(得分:0)

您应该使用SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country FROM my_db_client_total AS ct CROSS JOIN my_db_client_pro AS cp ON ct.CLIENT_ID = cp.CLIENT_ID

在这里查看:https://technet.microsoft.com/en-us/library/ms191472(v=sql.105).aspx

示例代码:

.textValue()

答案 4 :(得分:0)

如果您加入2个表,为什么不在查询中使用右侧表而不是在其上创建子查询?

试试这个(只有加入):

SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country 
  FROM my_db_client_total, my_db_client_pro
 WHERE my_db_client_total.email <> ''
   AND my_db_client_total.country = '120'
   AND my_db_client_total.email = my_db_client_pro.email;

或者这个(只有子查询):

SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country 
  FROM my_db_client_total
 WHERE my_db_client_total.email <> ''
   AND my_db_client_total.country = '120' 
   AND my_db_client_total.email IN (SELECT my_db_client_pro.email FROM my_db_client_pro);