简单的SQL查询将永远持续

时间:2018-09-20 13:47:33

标签: mysql sql database mysql-workbench

我正在adresses.loc[:,'(Latitude '+u"\u00B1"+'dd,dddddd, Longitude '+u"\u00B1"+'ddd,dddddd)'] = df_receivers[['Latitude '+u"\u00B1"+'dd,dddddd', 'Longitude '+u"\u00B1"+'ddd,dddddd']].apply(lambda x : '({},{})'.format(x[0],x[1]), axis=1) 计算机上使用print("Importing modules...") import pandas as pd import pyodbc import os import pantab import datetime as dt from datetime import timedelta print("Done importing modules.") server = 'server' db = 'db' conn_sql = pyodbc.connect('DRIVER={SQL Server};SERVER=' + server + ';DATABASE=' + db + ';Trusted_Connection=yes') sql_query = open('sql.sql', 'r').read() df_sql_output = pd.read_sql_query(sql_query, conn_sql) now = dt.datetime.today() - timedelta(days=1) now = now.strftime('%Y-%m-%d') df_sql_output.to_csv(r'path ' +now + '.csv') mysql-workbench服务器,其RAM为16 GB。

我有一个名为mysql的架构,还有两个表,分别为:ubunt 18ips。 在table1table2中,有两个字段:table1table2,bit是string类型。我有很多记录。 ip有779938条记录,而description有136657条记录。

我需要进行联合查询以找到table1table2ip开头但不包含{{1} },并且不包含table2。同时,这些descriptionstr1%中的描述不是以str2开头,而是包含str3ip

这是我的查询

table1

但是,查询永远不会结束。持续时间为str1%,但我从未得到结果。你能帮忙吗?

编辑:

这是SHOW CREATE TABLE和

1)str2 ips str3表2 SELECT COUNT(`table2`.`ip`) FROM `ips`.`table2`, `ips`.`table1` WHERE `table2`.`ip` = `table1`.`ip` AND (LOWER(`table1`.`description`) NOT LIKE 'str1%' AND (LOWER(`tabl1`.`description`) LIKE '%-str2-%' OR LOWER(`table1`.`description`) LIKE '%-str3-%' ) ) AND (LOWER(`table2`.`description`) LIKE 'str1%' AND LOWER(`table2`.`description`) NOT LIKE '%-str2-%' AND LOWER(`table2`.`description`) NOT LIKE '%-str3-%' );

?

2)SHOW CREATE TABLE ips .表1 ;

CREATE TABLE `table2` (
  `ip` varchar(500) DEFAULT NULL,
  `description` varchar(500) DEFAULT NULL,
  `type` varchar(500) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1

3)SHOW CREATE TABLE

.

编辑2:

;字段的数据是以下格式的字符串:CREATE TABLE `table1` ( `ip` varchar(500) DEFAULT NULL, `description` varchar(500) DEFAULT NULL, `type` varchar(500) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 EXPLAIN <query>字段的格式为:# id, select_type, table, partitions, type, possible_keys, key, key_len, ref, rows, filtered, Extra 1, SIMPLE, table2, , ALL, , , , , 136109, 100.00, Using where 1, SIMPLE, table1, , ALL, , , , , 786072, 10.00, Using where; Using join buffer (Block Nested Loop)

2 个答案:

答案 0 :(得分:1)

先前有关索引的答案可能会优化查询。可能是正确的。但是很抱歉,我必须检查用于解决问题的答案。感谢@Raymond Nijland率先指出了索引问题,使我想起了主键。

问题的根源是查询中的两个表都没有主键。主键必须用于唯一且不为null的键。就我而言,我已经准备好将ip字段作为主键进行服务器处理。由于我使用的是mysql- workbench,因此我右键单击表格,单击Alter Table,然后按如下所示检查适当字段的主键:

enter image description here

那解决了我的问题。

答案 1 :(得分:0)

由于SQL计划程序未使用任何索引,因此您在执行计划中获得了ALL运算符。它正在对两个表执行全表扫描。

当您选择超过5%的行时,全表扫描可能是最佳选择。在您的情况下,如果您的字符串前缀“ str1”有一个字母,则可能会很好。如果它有多个字符,则索引上的用法可以大大提高性能。

现在,您正在执行的比较不是一个简单的比较。您不是在比较列的值,而是在比较表达式的结果:LOWER(table1.description)。因此,如果您想快速查询,则需要创建虚拟列并为其建立索引。这在MySQL 5.7和更高版本上可用:

alter table table1 add lower_desc varchar(50) 
  generated always as (LOWER(description)) virtual;
create index ix1 on table1 (lower_desc);

alter table table2 add lower_desc varchar(50) 
  generated always as (LOWER(description)) virtual;
create index ix2 on table2 (lower_desc);

当前缀包含两个或多个字符时,这些索引将使您的查询更快。再次获得执行计划。现在,操作员ALL不再在那里(INDEX操作员现在应该出现在他们的位置)。

偶然地,我认为您错过了查询中的联接。我认为它应该看起来像(我添加了第三行):

SELECT COUNT(`table2`.`ip`)
FROM `ips`.`table2`
JOIN `ips`.`table1` on `ips`.`table1`.ip = `ips`.`table2`.ip
WHERE `table2`.`ip` = `table1`.`ip`
       AND (LOWER(`table1`.`description`) NOT LIKE 'str1%' 
             AND (LOWER(`tabl1`.`description`) LIKE '%-str2-%' 
                   OR LOWER(`table1`.`description`) LIKE '%-str3-%'
                 )
            )
       AND (LOWER(`table2`.`description`) LIKE 'str1%'
            AND LOWER(`table2`.`description`) NOT LIKE '%-str2-%' 
            AND LOWER(`table2`.`description`) NOT LIKE '%-str3-%'
           );

此外,要优化联接性能,您将需要以下所示的一个(或两个)索引:

create index ix3 on table1 (ip);
create index ix4 on table2 (ip);