我一直在遇到性能问题,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
答案 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)
(并显示创建表,以便我们知道我们正在使用的是什么。)