0

我正在开发一个应用程序,我从该程序创建查询字符串并将其传递给一个存储过程,其中包括四个Prepared statements. 传递变量后,语句如下,

DROP TABLE IF EXISTS tbl_correlatedData;

CREATE TABLE tbl_correlatedData 
SELECT t0.*,t1.counttimeStamplocalIp,t2.countlocalPort,t3.countlocalGeo,t4.countisp,t5.countforeignip,t6.countforeignPort,t7.countforeignGeo,t8.countinfection 
FROM tbl_union_threats t0 
LEFT JOIN tbl_tsli t1 
USING (timeStamp,localIp) LEFT JOIN tbl_tslilp t2 USING (timeStamp,localIp,localPort) 
LEFT JOIN tbl_tslilplg t3 
USING (timeStamp,localIp,localPort,localGeo) 
LEFT JOIN tbl_tslilplgisp t4 
USING (timeStamp,localIp,localPort,localGeo,isp) 
LEFT JOIN tbl_tslilplgispfi t5 
USING (timeStamp,localIp,localPort,localGeo,isp,foreignip) 
LEFT JOIN tbl_tslilplgispfifp t6 
USING (timeStamp,localIp,localPort,localGeo,isp,foreignip,foreignPort) 
LEFT JOIN tbl_tslilplgispfifpfg t7 
USING (timeStamp,localIp,localPort,localGeo,isp,foreignip,foreignPort,foreignGeo) 
LEFT JOIN tbl_tslilplgispfifpfginf t8 USING (timeStamp,localIp,localPort,localGeo,isp,foreignip,foreignPort,foreignGeo,infection)
GROUP BY timeStamp,localIp;

ALTER TABLE tbl_correlatedData 
MODIFY timeStamp VARCHAR(200) NOT NULL, 
MODIFY localIp VARCHAR(200) NOT NULL, 
MODIFY localPort VARCHAR(200) NOT NULL, 
MODIFY localGeo VARCHAR(200) NOT NULL, 
MODIFY isp VARCHAR(200) NOT NULL, 
MODIFY foreignip VARCHAR(200) NOT NULL, 
MODIFY foreignPort VARCHAR(200) NOT NULL, 
MODIFY foreignGeo VARCHAR(200) NOT NULL, 
MODIFY infection VARCHAR(200) NOT NULL;

CREATE INDEX id_index ON tbl_correlatedData (timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection);

但是当进程到达索引查询时,它会给出一个错误说,

Incorrect key file for table 'tbl_correlateddata'; try to repair it

仅供参考: 我正在使用 xampp 服务器的驱动器上的 19 GB 可用空间的 Windows Vista 32 位上尝试此操作,并且创建的表在 phpMyadmin 上显示其大小为 25Mb。

编辑: 当我尝试使用REPAIR TABLE tbl_correlateddata以下内容修复它时,

Table                                |  Op    | Msg_type |  Msg_text
-----------------------------------------------------------------------------------------------------------------
db_threatanalysis.tbl_correlateddata |  repair| Error    |  Table 'db_threatanalysis.tbl_correlateddata' doesn...
db_threatanalysis.tbl_correlateddata |  repair| status   |  Operation failed

非常感谢您的帮助..提前:)

4

3 回答 3

2

您正在尝试创建复合(多列)索引,这对于 Innodb 来说太长了。

您有 9 列,每列 VARCHAR(200),因此总索引宽度为 1800 个字符。根据MySQL 文档,Innodb 密钥限制为 3072 个字符。所以,你应该没问题,但是,不能保证ALTER TABLE ... MODIFY ...能够将所有列宽减少到 200 或更小,所以即使一个保持在 4000 个字符左右,你也会收到这个错误。

解决方案:

减少复合索引中的字段数。分析将要查询这个生成的表的查询,并且只创建真正需要的索引。我想它们中的大多数将是单列索引。

此外,您为什么需要 VARCHAR(200) 来存储诸如时间戳、ip、端口等简单的东西,这很奇怪。您可能很容易将它压缩到 10 个字节或更少,然后就可以收工了。

于 2013-01-07T08:17:45.233 回答
2

您的密钥大小可能太长。我在本地 MySQL 安装上尝试了类似的东西。由于我没有您的表,我无法运行 CREATE TABLE 语句。由于我的数据库是为 UNICODE 设置的,因此我的密钥大小超过 4000 字节。MySQL InnoDB 只能创建键大小为 3072 字节的索引。

我的代码如下所示:

CREATE TABLE tbl_correlatedData 
(
  `timeStamp` VARCHAR(200) NOT NULL, 
   localIp VARCHAR(200) NOT NULL, 
   localPort VARCHAR(200) NOT NULL, 
   localGeo VARCHAR(200) NOT NULL, 
   isp VARCHAR(200) NOT NULL, 
   foreignip VARCHAR(200) NOT NULL, 
   foreignPort VARCHAR(200) NOT NULL, 
   foreignGeo VARCHAR(200) NOT NULL, 
   infection VARCHAR(200) NOT NULL
  );

CREATE INDEX id_index ON tbl_correlatedData
       (timeStamp,
        localIp,
        localPort,
        localGeo,
        isp,
        foreignIp,
        foreignPort,
        foreignGeo,
        infection
 );

这导致了错误:

Error Code: 1071. Specified key was too long; max key length is 3072 bytes

请在此处阅读有关大小限制的信息:http: //dev.mysql.com/doc/refman/5.5/en/innodb-restrictions.html。我怀疑你有这个问题。

于 2013-01-07T08:19:33.437 回答
1

innodb 表的索引键前缀最多可达 767 个字节,而 myisam 表的索引键前缀约为 1000 个字节

mysql innodb 的总索引长度为 3072

首先,您只需检查索引的长度,如果可能的话,减少所有列的大小 varchar(100)

如果可能,创建单独的索引(如果它符合您的要求)

看链接

http://dev.mysql.com/doc/refman/5.0/en//create-index.html

http://bugs.mysql.com/bug.php?id=6604

于 2013-01-07T09:37:47.827 回答