由于BLOB字段(不能在另一个表中移动),MySQL查询速度很慢

Van*_*ine 5 mysql blob

我正在开发基于MySql数据库的PyQT软件.数据库包含一些记录的电信号,以及描述这些信号的所有信息(采样率,重新编码日期等).

有了一个想法,一个数据库包含10 000到10万行,总大小> 10Gb.所有这些数据都存储在专用服务器上.实际上,大多数数据都是信号本身,它位于名为analogsignal.signal的BLOB字段中(见下文)

这是数据库的体系结构:http://packages.python.org/OpenElectrophy/_images/simple_diagram1.png

我无法更改它(我可以添加列和索引,但我无法移动或删除现有列).

在软件中,我需要列出所有的analogsignal列(id,name,channel,t_start,sampling_rate),但analogsignal.signal除外,后者通过analogsignal.id调用.所以我正在做以下查询

SELECT block.id,block.datetime,segment.id,analogsignal.id,analogsignal.name,analogsignal.channel,analogsignal.sampling_rate,block.fileOrigin,block.info

FROM segment,block,analogsignal

WHERE block.id = segment.id_block

AND segment.id = analogsignal.id_segment

ORDER BY analogsignal.id

问题是,由于analogsignal.signal列的存在,我的查询很慢(如果请求不在缓存中,则> 10分钟).如果我正确理解正在发生的事情,则表格逐行读取,包括analogsignal.signal,即使analogsignal.signal不在SELECT字段中.

有没有人知道如何优化数据库或查询而不在另一个表中移动BLOB(我同意这将更合乎逻辑,但我不控制这一点).

谢谢!

这是AnalogSignal表的CREATE TABLE命令(从注释中拉出/格式化)

CREATE TABLE analogsignal 
  ( id int(11) NOT NULL AUTO_INCREMENT, 
    id_segment int(11) DEFAULT NULL,
    id_recordingpoint int(11) DEFAULT NULL, 
    name text, 
    channel int(11) DEFAULT NULL, 
    t_start float DEFAULT NULL, 
    sampling_rate float DEFAULT NULL, 
    signal_shape varchar(128) DEFAULT NULL, 
    signal_dtype varchar(128) DEFAULT NULL, 
    signal_blob longblob, Tag text, 
    PRIMARY KEY (id), 
    KEY ix_analogsignal_id_recordingpoint (id_recordingpoint),
    KEY ix_analogsignal_id_segment (id_segment) 
  ) ENGINE=MyISAM AUTO_INCREMENT=34798 DEFAULT CHARSET=latin1 ;
Run Code Online (Sandbox Code Playgroud)

编辑:问题解决了,这里有关键点:

- 我必须添加一个多列索引,在analogsignal表中的所有SELECT字段上输入INDEX
- 'TEXT'类型的列阻止了索引的使用.我在VARCHAR(xx)中转换了这些TEXT字段.为此我使用了这个简单的命令:

SELECT MAX(LENGTH(field_to_query))FROM table_to_query

检查转换前的最小文本长度,以确保我不会丢失任何数据

ALTER TABLE table_to_query CHANGE field_to_query field_to_query VARCHAR(24)

我首先使用VARCHAR(8000),但是使用此设置,VARCHAR就像一个TEXT字段,并且索引不起作用.VARCHAR(24)没有这样的问题.如果我是对的,查询中的总TEXT长度(包括所有字段)必须不能传递1000个字节

然后我如上所述索引所有列,索引中没有大小参数

最后,使用更好的查询结构(谢谢DRapp),改进了查询.我从215s传递到0.016s进行查询,没有缓存...

DRa*_*app 4

除了尝试通过将数据放入外部物理文件并仅将路径\文件名存储在相应的记录中来缩小“blob”列要求之外,我还尝试以下方法作为替代方案......

我将反转查询并将 AnalogSignal 表放在第一位,因为它是 order by 子句的基础,并将查询向后反转到块。此外,为了避免读取每个文字数据行,如果您在输出中所需的所有列上构建复合索引,它将创建一个更大的索引,但查询将直接从键表达式中提取值,而不是从读回实际的数据行。

在 AnalogSignal 上创建索引 KeyDataOnly(id、id_segment、name、channel、sampling_rate)

SELECT STRAIGHT_JOIN
      block.id, 
      block.datetime, 
      segment.id, 
      analogsignal.id, 
      analogsignal.name, 
      analogsignal.channel, 
      analogsignal.sampling_rate, 
      block.fileOrigin, 
      block.info
   FROM 
      analogsignal
         JOIN Segment
            on analogsignal.id_segment = segment.id
            JOIN block
               on segment.id_block = block.id
   ORDER BY 
      analogsignal.id
Run Code Online (Sandbox Code Playgroud)