【发布时间】:2014-11-12 06:29:15
【问题描述】:
我有以下表格。
CREATE TABLE `media_scores` (
`media_id` int(10) unsigned NOT NULL,
`sorting_score` float unsigned NOT NULL DEFAULT '0',
`date_added` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`date_updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`media_id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `media_restrict` (
`media_id` int(11) NOT NULL,
`restrict_type` enum('exclude','include') NOT NULL,
`country_code` char(2) NOT NULL,
PRIMARY KEY (`media_id`,`restrict_type`,`countryCode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表 media_scores 有 180 万条记录。 表 media_restrict 具有相同或更多的记录。
以下是里面的一些示例数据: media_scores
+----------+---------------+-------------+--------------+
| media_id | sorting_score | date_added | date_updated |
+----------+---------------+-------------+--------------+
| 1 | 25 | 2014-11-05 | 0000-00-00 |
| 2 | 16 | 2014-11-05 | 0000-00-00 |
| 3 | 33 | 2014-11-05 | 0000-00-00 |
| 4 | 11 | 2014-11-04 | 0000-00-00 |
+----------+---------------+-------------+--------------+
媒体限制
+----------+---------------+--------------+
| media_id | restrict_type | country_code |
+----------+---------------+--------------+
| 1 | exclude | US |
| 1 | exclude | UK |
| 2 | include | US |
| 2 | include | CA |
| 3 | include | CN |
+----------+---------------+--------------+
我正在运行以下查询:
SELECT ms.*
FROM media_scores as ms
LEFT OUTER JOIN media_restrict AS mr
ON ms.media_id = mr.media_id and mr.restrict_type = 'exclude' and mr.country_code = 'CA'
LEFT OUTER JOIN media_restrict AS mr2
ON ms.media_id = mr2.media_id AND mr2.restrict_type = 'include' AND mr2.country_code = 'CA'
LEFT OUTER JOIN media_restrict AS mr3
ON ms.media_id = mr3.media_id AND mr3.restrict_type = 'include' AND mr3.country_code != 'CA'
WHERE mr.media_id IS NULL AND
(CASE mr2.media_id WHEN ms.media_id THEN NULL ELSE mr3.media_id END) IS NULL;
实现这一目标:
+----------+---------------+------------+--------------+
| media_id | sorting_score | date_added | date_updated |
+----------+---------------+------------+--------------+
| 1 | 25 | 2014-11-05 | 0000-00-00 |
| 2 | 16 | 2014-11-05 | 0000-00-00 |
| 4 | 11 | 2014-11-04 | 0000-00-00 |
+----------+---------------+------------+--------------+
在小子集上 - 查询运行良好。 在 1.8M 上,我遇到了可扩展性问题。
我最终想要实现的基本目标是将 media_scores 中的项目显示给仅允许的国家/地区。
我在基础架构方面非常灵活,因此 MySQL 可能不是解决方案,但它是我能想到的全部。
随着我填写更多数据和更多国家/地区限制,数据集将会增长。
如何在更大范围内有效地根据国家/地区限制我的数据。任何给定的服务如何检查内容限制(例如 Youtube 不能根据国家/地区显示内容)。
有两件事需要考虑:速度和准确性。 当前的基准大约是 13 秒,如果我将其作为数据集加载,然后我必须对其进行操作 - 它的时间太长了。准确性意味着我需要确保获得所需的正确结果。目前提到的查询是正确的。
注意:数据经常更新,但不是每分钟更新一次(我会说每小时左右可能更多) - 因此 Vertica 可以提供大数据集以进行高效查询,但由于 Vertica 不能很好地支持更新或删除 - 它排除了这一点。
【问题讨论】:
标签: mysql database scalability