I use Django ORM to query data, and I get almost 2 million rows in this table. I tried
app_count = App.objects.count()
and
from django.db import connection cursor = connection.cursor() cursor.execute('''SELECT count(*) FROM app''')
Mysql log slow_query gave me
Time: 2017-04-27T09: 18: 38.809498Z
User @ Host: www [www] @ [172.19.0.3] Id: 5
Query_time: 4.107433 Lock_time: 0.004405 Rows_sent: 1 Rows_examined: 0
use app_platform; SET timestamp = 1493284718; SELECT count (*) FROM application;
This request took more than 4 seconds, but when I used mysql client and mysql shell to execute this request
mysql> select count(*) from app; +----------+ | count(*) | +----------+ | 1870019 | +----------+ 1 row in set (0.41 sec)
Just take me for 0.4 seconds, the difference is 10X, why and how to improve it.
EDIT
here is my model
class AppMain(models.Model): """ """ store = models.ForeignKey("AppStore", related_name="main_store") name = models.CharField(max_length=256) version = models.CharField(max_length=256, blank=True) developer = models.CharField(db_index=True, max_length=256, blank=True) md5 = models.CharField(max_length=256, blank=True) type = models.CharField(max_length=256, blank=True) size = models.IntegerField(blank=True) download = models.CharField(max_length=1024, blank=True) download_md5 = models.CharField(max_length=256, blank=True) download_times = models.BigIntegerField(blank=True) snapshot = models.CharField(max_length=2048, blank=True) description = models.CharField(max_length=5000, blank=True) app_update_time = models.DateTimeField(blank=True) create_time = models.DateTimeField(db_index=True, auto_now_add=True) update_time = models.DateTimeField(auto_now=True) class Meta: unique_together = ("store", "name", "version")
EDIT 2
And I use Docker and docker-compose for my project
version: '2' services: mysqldb: restart: always image: mysql:latest ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: just_for_test MYSQL_USER: www MYSQL_PASSWORD: www MYSQL_DATABASE: app_platform volumes: - mysqldata:/var/lib/mysql - ./config/:/etc/mysql/conf.d - ./log/mysql/:/var/log/mysql/ web: restart: always build: ./app_platform/app_platform env_file: .env environment: PYTHONPATH: '/usr/src/app/app_platform' command: bash -c "gunicorn --chdir /usr/src/app/app_platform app_platform.wsgi:application -k gevent -w 6 -b :8000 --timeout 8000 --reload" volumes: - ./app_platform:/usr/src/app - ./sqldata:/usr/src/sqldata - /usr/src/app/static ports: - "8000" dns: - 114.114.114.114 - 8.8.8.8 links: - mysqldb nginx: restart: always build: ./nginx/ ports: - "80:80" volumes: - ./app_platform:/usr/src/app - ./nginx/sites-enabled/:/etc/nginx/sites-enabled links: - web:web volumes: mysqldata:
And my django settings look like this:
import os from django.utils.translation import ugettext_lazy as _ LANGUAGES = ( ('en', _('English')), ('zh-CN', _('Chinese')), ) LANGUAGE_CODE = 'zh-CN' BASE_DIR = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) LOCALE_PATHS = ( os.path.join(BASE_DIR, "locale"), )
Information about my application table
CREATE TABLE `app` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(256) NOT NULL, `version` varchar(256) NOT NULL, `developer` varchar(256) NOT NULL, `md5` varchar(256) NOT NULL, `type` varchar(256) NOT NULL, `size` int(11) NOT NULL, `download` varchar(1024) NOT NULL, `download_md5` varchar(256) NOT NULL, `download_times` bigint(20) NOT NULL, `snapshot` varchar(2048) NOT NULL, `description` varchar(5000) NOT NULL, `app_update_time` datetime(6) NOT NULL, `create_time` datetime(6) NOT NULL, `update_time` datetime(6) NOT NULL, `store_id` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `app_store_id_6822fab1_uniq` (`store_id`,`name`,`version`), KEY `app_7473547c` (`store_id`), KEY `app_developer_b74bcd8e_uniq` (`developer`), KEY `app_create_time_a071d977_uniq` (`create_time`), CONSTRAINT `app_store_id_aef091c6_fk_app_scrapy_appstore_id` FOREIGN KEY (`store_id`) REFERENCES `app_scrapy_appstore` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1870020 DEFAULT CHARSET=utf8;
EDIT 3
Here is the EXPLAIN SELECT COUNT (*) FROM app ;
mysql> EXPLAIN SELECT COUNT(*) FROM `app`; +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ 1 row in set, 1 warning (0.00 sec)
EDIT 4
Here is my mysql.cnf
innodb_read_io_threads=12 innodb_write_io_threads=12 innodb_io_capacity=300 innodb_read_io_threads=12 innodb_write_io_threads=12
My docker settings - 2 CPUS and 4 GB of memory
EDIT 5
When I ran the ORM request inside the django shell, I just took 0.5-1 seconds. So, the problem is docker settings? or maybe layoffs?