Медленный SQL в большой таблице, фильтрация по временным меткам (int12) - PullRequest
0 голосов
/ 22 августа 2011

У меня проблема с медленным запросом, я делаю "простой" выбор ... я не понимаю, в чем проблема ... это большая таблица ... но это простой запрос ..

Таблицы:

business: (1.000.000 reg)
id (INDEX PRIMARY INT(11) UNSIGNED)
active (INDEX TINYINT(1))

products: (32.000.000 reg)
id (INDEX PRIMARY INT(11) UNSIGNED)
business_id (INDEX INT(11) UNSIGNED)
offer_start (INDEX INT(12) UNSIGNED) (timestam unix)
offer_end (INDEX INT(12) UNSIGNED) (timestamp unix)
price_offer (VARCHAR(10)) (price with decimals)
active (INDEX TINYINT(1))

business.id, products.id, products.offer_start и products.offer_end равны INDEX (разделены)

Когда я делаю это:

SELECT SQL_NO_CACHE * FROM products 
LEFT JOIN business ON business.id = products.business_id 
WHERE
 (business.active = '1' AND business.paylimit > 1314029906) 
AND 
 (products.active = '1' AND products.offer_start < 1314029906 AND products.offer_end > 1314029906 AND products.price_offer > 0) 
LIMIT 0,10

Взять 21 секунду. Проблема заключается в следующем: products.offer_start < 1314029906 AND products.offer_end > 1314029906 требуется ~ 20 секунд, чтобы дать мне результаты

Можно ли сделать этот запрос, фильтруя другие формы для ускорения?

Ответы [ 2 ]

2 голосов
/ 22 августа 2011

Некоторые примечания о вашей схеме таблицы:

  1. offer_start (INDEX INT (12) UNSIGNED) - 12 не имеет смысла, поскольку максимальное количество символов в INT равно 11. То же самое для offer_end
  2. active (INDEX TINYINT (1)) - индекс бесполезен, так как количество элементов на 1000000 будет 2 - 1 или 0
  3. price_offer (VARCHAR (10)) - вы можете использовать float или десятичное для этого. products.price_offer> 0 будет работать быстрее.
0 голосов
/ 22 августа 2011

Попробуйте

SELECT SQL_NO_CACHE * FROM products 
    LEFT JOIN business ON business.id = products.business_id 
WHERE business.paylimit > 1314029906
    AND products.offer_start < 1314029906
    AND products.offer_end > 1314029906
    AND products.price_offer > 0
    AND business.active = '1'
LIMIT 0,10

MySQL обрабатывает фильтры слева направо, поэтому убедитесь, что условие, которое является наиболее селективным (возвращает наименьшее количество строк), находится слева. Наличие business.active = '1' на самой левой стороне условия может использовать индекс, но если его селективность равна 50%, то остальное условие не использует индекс.

Вы можете прочитать Как в MySQL используются индексы в руководстве.

Edit: Краткое объяснение того, как MySQL использует индексы: 3 способа, которыми MySQL использует индексы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...