Django数据库查询很慢

时间:2015-02-25 01:26:16

标签: python mysql django

我一直在遇到性能问题,Django选择我认为是中等规模的查询。

以下是直接在Mysql中运行django查询的示例;

SELECT * FROM `website_datapoolposition` WHERE (`website_datapoolposition`.`data_pool_id` = 596 AND `website_datapoolposition`.`timestamp` <= '2015-01-24 23:31:33' AND `website_datapoolposition`.`timestamp` >= '2015-01-24 19:01:30');

8063行(0.05秒)

这对我来说似乎很合理。此表中有大约7百万行,时间戳已编入索引。

然而,当django将这些数据作为值拉出时,需要.7秒。 django是否假设为原始sql添加14倍的开销?我用Google搜索了我能找到的每一个技巧,似乎没有什么能像我期望的那样让我降到80毫秒。

编辑:

以下是此表的django def:

#define my models
id          = models.AutoField(primary_key=True)
car         = models.ForeignKey(Car)
lat         = models.DecimalField( max_digits=16, decimal_places=12 )
lng         = models.DecimalField( max_digits=16, decimal_places=12 )
speed       = models.DecimalField( max_digits=5, decimal_places=2, default=0 )
total = models.DecimalField( max_digits=12, decimal_places=2, null=True, blank=True)
dist        = models.DecimalField( max_digits=12, decimal_places=2, null=True, blank=True)
timestamp   = models.DateTimeField( db_index=True )

以下是show create table的架构:

app_pos | CREATE TABLE `app_pos` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`lat` decimal(16,12) NOT NULL,
`lng` decimal(16,12) NOT NULL,
`speed` decimal(5,2) NOT NULL,
`timestamp` datetime NOT NULL,
`car_id` int(11) NOT NULL,
`total` decimal(12,2) DEFAULT NULL,
`dist` decimal(12,2),
PRIMARY KEY (`id`),
KEY `app_pos_fa16e375` (`car_id`),
KEY `app_pos_timestamp_f13fe0c76a90341_uniq` (`timestamp`),
KEY `app_pos_timestamp_343244cae95f1483_uniq` (`timestamp`),
CONSTRAINT     `app_dat_car_id_feb2a18963295a287_fk_app_car_id` FOREIGN   KEY (`car_id`) REFERENCES `app_car` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7000000 DEFAULT CHARSET=utf8

2 个答案:

答案 0 :(得分:0)

当您在MySQL cli中运行此查询时,您将获得在服务器上执行查询的时间,但不会将行传输到另一个进程(甚至是机器)并从这些行构建8K重的对象。

从SQL获取数据的最快的django方式是:

data = DataPoolPosition.objects.filter(...).values_list('field1', 'field2')

您将获得迭代器,其中每一行将由元组表示。

另一种选择是直接execute custom SQL,但我不认为你会比values_list()选项获得更大的速度提升。

答案 1 :(得分:0)

ADD INDEX(data_pool_id, timestamp)

(并显示创建表,以便我们知道我们正在使用的是什么。)