Реализация в реальном времени с несколькими фильтрами с MySQL

Я разрабатываю приложение PHP для портала недвижимости, и у меня есть база данных MySQL с таблицей свойств. Эта таблица содержит около 500 000 строк и около 20 столбцов для объектов свойств. Предположим, что каждая функция является целым числом.

Примеры функций:

  • количество комнат в квартире (1-10)
  • тип здания (1-20)
  • состояние здания (1-10)

Мне нужно реализовать веб-страницу с панелью навигации в режиме реального времени с несколькими фильтрами. Идея состоит в том, что пользователи могут выбрать несколько функций, которые будут равны определенным значениям.
Например: 1-2 комнаты («1», «2»), здание 196x («6»), состояние среднее, хорошее или отличное («3», «4», «5»), в частности Город.

Ключевым требованием является возможность для пользователей видеть количество подходящих свойств рядом с каждым фильтром объектов с учетом выбранных фильтров.

Вот пример, как это должно выглядеть:

Rooms: 1[X], 2[X], 3[ ] (15000 more), 4[ ] (10000 more)
State: bad[ ] (1000 more), average[X], excellent[X]
Year: 1950[ ] (19000), 1960[ ] (20000), 1970[ ] (18000)
City: A[ ] (25000), B[ ] (18000), C[ ] (30000)
Price: <100000[ ] (20000), >100000[ ] (30000)

«[]» Обозначает пустой флажок (т.е. значение фильтра не выбрано), а «[X]» обозначает установленный флажок (т.е. значение фильтра выбрано).

Когда пользователь выбирает конкретное значение функции, скажем, City = London, цифры должны измениться, потому что они теперь ограничены предыдущими выборами:

Rooms: 1[X], 2[X], 3[ ] (5000 more), 4[ ] (5000 more)
State: bad (1000 more), average[X], excellent[X]
Year: 1950 (19000), 1960 (20000), 1970 (18000)
City: A[X], B (+4000), C (+3000)
Price: <100000 (5000), >100000 (6000)

Я попытался использовать следующий запрос SQL для каждой функции (X):

SELECT FeatureX, COUNT(*) AS num FROM properties WHERE selectedFeature1=Val1 AND selectedFeature2=Val2 ... AND selectedFeatureN=ValN GROUP BY featureX;

Однако набор этих запросов занимает несколько секунд, и мне нужно, чтобы это работало в режиме реального времени, т.е. <200 мс на бэкэнде.

Я пытался сохранить всю таблицу в общей памяти, но unserialize () массива с 500 000 записей также занимает около 1 с.

Единственное решение, которое я нашел, — это разработка отдельного приложения (например, в NodeJS), которое хранит данные в памяти в виде массива объектов и предоставляет API для основного приложения PHP. Это приложение обновляет данные из базы данных MySQL каждую минуту.

Однако, прежде чем приступить к реализации этого, я хотел бы спросить, есть ли какое-либо решение, основанное на самом MYSQL для такой задачи?

Если нет, то есть ли чисто PHP-решение?

У вас есть какие-то общие рекомендации, как подходить к решению этой задачи?

2

Решение

Не все может быть решено в базе данных.

Вы должны посмотреть на все 500К строк. Маловероятно, что какой-либо индекс поможет с более чем малой долей возможных запросов. Итак … Я предлагаю вам сохранить все данные в оперативной памяти и иметь некоторую быструю обработку (например, C ++) для выполнения всех из них.

Данные должны быть (в терминах MySQL) TINYINT UNSIGNED что-то вроде char unsigned, Возможно, данные могут быть сохранены в 20 байтов, один байт на функцию? Это всего 10 МБ в C ++, 30-100 МБ в MySQL, 400 МБ в PHP. MySQL может хранить данные в BINARY(20) упростить выборку за счет вставки / обновления.

Используйте MySQL в качестве «источника правды» и периодически загружайте его в свой процессор (вы предложили 1 минуту и ​​Node.js). Затем сфокусируйтесь на оптимизации счета.

Большинство языков в наши дни являются «интерпретирующими», следовательно, некоторые накладные расходы. C или C ++ являются двумя из немногих, которые работают на «машинном» уровне. Я почти уверен, что они могут выполнить вычисления 10M менее чем за 200 мс; Я сомневаюсь, что любой интерпретирующий язык может.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]