我正在运行一个产生多个进程的Python脚本。该进程调用一个方法,该方法每次针对特定条件运行SELECT
查询并获取N条记录。我面临的问题是每个进程几乎同时生成,SELECT
同时执行,因此许多进程针对SELECTs获取相同的记录
我想知道是否有办法选择独特的记录?我知道Order by Rand()
,但这看起来很昂贵。
下面给出的表格式:
+-------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| url | varchar(255) | NO | MUL | NULL | |
| source_file | varchar(255) | NO | | | |
| proxy_url | varchar(255) | NO | | NULL | |
| duration | int(11) | NO | | NULL | |
| status | int(11) | NO | MUL | NULL | |
| updated_at | datetime | YES | | CURRENT_TIMESTAMP | |
+-------------+--------------+------+-----+-------------------+----------------+
由于
答案 0 :(得分:0)
必须在执行SELECT之前或返回结果集之后在应用程序级别完成。在选择之前我肯定会选择。假设有5个进程生成,每个进程返回10行的结果集。您可以创建5个10个数字的列表,并将其传递给每个进程。这是我将如何做到这一点。 (这假定主键是顺序的,从0开始,并且没有从表中删除任何记录的情况):
首先,主脚本执行查询以获取表中记录的计数。假设这返回10000.我会做这样的事情:
from random import shuffle
process_count = 5
need = 10
list_of_lists = []
values = list(range(10000))
shuffle(values)
for i in range(process_count):
start = i * need
m = values[start:start+10]
list_of_lists.append(m)
或者你可以绕过循环并使用列表理解:
list_of_lists = [ values[i*need:i*need+10] for i in range(process_count)]
list_of_lists现在包含5个列表,其中包含0和表大小之间的10个有效随机数。此时,迭代list_of_lists并将列表输出到生成的进程。在每个生成的进程中,该列表用于从TABLE生成SELECT,其中ID为IN()语句。
+++++++++++编辑++++++++++++++++++
定期删除记录的事实会带来一些问题。首先,您不能简单地对表进行计数,因为由于存在间隙,因此max id将大于表计数。您可以简单地返回所有id值,随机播放它们,并创建单个列表。随着表格变大,这可能是昂贵且不切实际的。 你可以通过发送一个类似这样的初始查询来解决这个问题:
select max(id) from <tablename>;
然后您可以生成如下列表:
values = list(range(max_id_value + 1))
此时您可以这样做:假设您需要从每个衍生进程返回10行。如果您发送每个10个数字的列表,如果发送的数字与ID不对应,则进程将发送少于10个。解决此问题的一种方法是向每个进程发送30个值的列表。然后在select查询中你可以添加LIMIT 10.你发送的数字将取决于id列表的稀疏程度。
希望这是有道理的