mysql udf json_extract in where子句 - 如何提高性能

时间:2014-10-31 08:10:17

标签: mysql json where-clause database-performance mysql-udf

如何在mysql数据库中有效搜索json数据?

我从labs.mysql.com安装了extract_json udf,并玩了一个2.750.000条目的测试表。

CREATE TABLE `testdb`.`JSON_TEST_TABLE` (
   `AUTO_ID` INT UNSIGNED NOT NULL AUTO_INCREMENT,
   `OP_ID` INT NULL,
   `JSON` LONGTEXT NULL,
PRIMARY KEY (`AUTO_ID`)) $$

示例JSON字段如下所示:

{"ts": "2014-10-30 15:08:56 (9400.223725848107) ", "operation": "1846922"}

我发现将json_extract放入select语句几乎没有性能影响。 即以下选择(几乎)具有相同的性能:

SELECT * FROM JSON_TEST_TABLE where OP_ID=2000000 LIMIT 10;

SELECT OP_ID, json_extract(JSON, "ts") ts, json_extract(JSON, "operation") operation FROM JSON_TEST_TABLE where OP_ID=2000000 LIMIT 10; 

但是,只要我将一个json_extract表达式放入where子句中,执行时间就会增加10倍或更多(我从2.5秒增加到30秒):

SELECT OP_ID, json_extract(JSON, "ts") ts, json_extract(JSON, "operation") operation FROM JSON_TEST_TABLE where json_extract(JSON, "operation")=2000000 LIMIT 10;

此时我认为我需要在插入时将所有要搜索的信息提取到单独的列中,如果我真的必须在json数据中搜索,我需要先缩小行数按其他标准搜索,但我想确保我没有遗漏任何明显的东西。 例如。我可以以某种方式索引json字段吗?或者我的选择语句写得不好么?

3 个答案:

答案 0 :(得分:2)

实际上在执行期间

SELECT * FROM JSON_TEST_TABLE where OP_ID=2000000 LIMIT 10;

json_extract()最多执行10次。

在此期间

SELECT OP_ID, json_extract(JSON, "ts") ts, json_extract(JSON, "operation") operation FROM JSON_TEST_TABLE where json_extract(JSON, "operation")=2000000 LIMIT 10;

将为每一行执行json_extract(),结果限制为10条记录,因此速度损失。 索引不会有任何帮助,因为处理时间比MySQL更耗尽外部代码。 Imho,在这种情况下最好的选择是优化的UDF。

答案 1 :(得分:1)

你可以试试这个: http://www.percona.com/blog/2015/02/17/indexing-json-documents-for-efficient-mysql-queries-over-json-data/

用于MySQL的Flexviews物化视图用于使用JSON_EXTRACT将JSON中的数据提取到另一个表中,该表可以被编入索引。

答案 2 :(得分:-2)

我认为如果对查询执行EXPLAIN,您会看到MySQL执行全表扫描,只是因为您的查询是在未编入索引的术语上。