<?xml version='1.0' encoding='UTF-8'?>
<rss version='2.0'>
	<channel>
		<title>cotonti.com : Вопрос про большую выборку в sql</title>
		<link>https://www.cotonti.com</link>
		<description>Laatste forum onderwerpen</description>
		<generator>Cotonti</generator>
		<language>en</language>
		<pubDate>Sat, 11 Apr 2026 16:53:52 -0000</pubDate>

		<item>
			<title>Kopusha</title>
			<description><![CDATA[<p>для каждого конкретного пользователя? для юзера 1 одни списки для юзера 2 (у него другой список друзей) другие и тд</p>

<p>и это выборка первых 30 записей, после почти сразу +30 инфинитскроллом и так далее</p>
<p class="updated"><strong>Added 1 minute later:</strong></p><p>пробую так</p>

<pre class="brush:as3;">
		$db-&gt;exec("
		    CREATE TEMPORARY TABLE temp_friends (
		        friend_id INT PRIMARY KEY
		    ) ENGINE=MEMORY;
		");
		if (!empty($friends_ids)) {
		    $placeholders = implode(',', array_fill(0, count($friends_ids), '?'));
		    $stmt = $db-&gt;prepare("INSERT INTO temp_friends (friend_id) VALUES ($placeholders)");
		    $stmt-&gt;execute($friends_ids);
		}		
		
		// Запрос с временной таблицей
		$totalitems = $db-&gt;query("SELECT COUNT(*) 
		    FROM $db_stories AS f 
		    LEFT JOIN $db_users AS u ON u.user_id=f.item_userid
		    LEFT JOIN temp_friends tf ON tf.friend_id = f.item_userid
		    $join_condition 
		    " . $where . "
		    $where_condition
		    $where_friends
		")-&gt;fetchColumn();

		$db-&gt;exec("DROP TEMPORARY TABLE IF EXISTS temp_friends;");
</pre>

<p> </p>
]]></description>
			<pubDate>Ma, 17 Feb 2025 10:03:41 -0000</pubDate>
			<link><![CDATA[https://www.cotonti.com/nl/forums?m=posts&q=9387&d=0#post48211]]></link>
		</item>
		<item>
			<title>Kort</title>
			<description><![CDATA[<p>Самое простое -- закэшировать результат на разумный срок</p>
]]></description>
			<pubDate>Ma, 17 Feb 2025 09:40:59 -0000</pubDate>
			<link><![CDATA[https://www.cotonti.com/nl/forums?m=posts&q=9387&d=0#post48210]]></link>
		</item>
		<item>
			<title>Kopusha</title>
			<description><![CDATA[<p>В $db_stories некоторые записи создаються "только для друзей", при этом item_only_friends у них == 1.</p>

<p>Есть таблица "с парами друзей", friendid/userid будет пара друзей, если они в "активной" дружбе - со статусом 1.</p>

<p>Мне нужно построить выборку в list.stories с зависимостью от того показываем ли мы историю этому конкретному пользователю или нет.</p>

<pre class="brush:php;">
if ($usr['id'])
		{
			//Get all friends of a user
			if (cache_exists('friendlist_'.$usr['id']) &amp;&amp; $cfg['apcu_cache'])
			{
				//получаем id пользователей которые у текущего в друзьях из кеша в виде 1 2 3 4 5
				$friends_ids = cache_get('friendlist_'.$usr['id']);
			}
			if (!isset($friends_ids) || !is_array($friends_ids)) 
			{
				global $db_cot_social_friendslist, $db_x;
				$db_cot_social_friendslist = (isset($db_cot_social_friendslist)) ? $db_cot_social_friendslist : $db_x . 'social_friendslist';
				//если в кеше их нет то получаем их из БД 
		        $friends_ids = $db-&gt;query("
		            SELECT 
		                CASE 
		                    WHEN userid = :userid THEN friendid 
		                    ELSE userid 
		                END AS friend_id
		            FROM $db_cot_social_friendslist 
		            WHERE status = 1 
		            AND (userid = :userid OR friendid = :userid)
		        ", [':userid' =&gt; $usr['id']])-&gt;fetchAll(PDO::FETCH_COLUMN) ?: [];

				$friends_ids = array_unique($friends_ids);			
				
				if(!empty($friends_ids))
				{
					if($cfg['apcu_cache']) 
					{
						cache_store('friendlist_'.$usr['id'], $friends_ids, 3200);
					}
				}
			}	
			//если пользователь не администратор
			if (!$usr['isadmin'])
			{
			    if (empty($friends_ids)) {
				    //и у него нет друзей - не показываем истории которые только для друзей
			        $where_friends = "AND (item_only_friends=0 OR item_userid=".$usr['id'].")";
			    } else {
				    //и у него есть друзья то показываем истории что для всех, которые его и которые для друзей и в списке его друзей есть автор истории
				    $where_friends = "AND (item_only_friends=0 OR item_userid=".$usr['id']." OR item_userid IN (".implode(',', array_map('intval', $friends_ids))."))";
			    }
			}
		}
		else
		{
			$where_friends = "AND (item_only_friends=0)";
		}

		$totalitems = $db-&gt;query("SELECT COUNT(*) FROM $db_stories AS f 
			$join_condition 
			LEFT JOIN $db_users AS u ON u.user_id=f.item_userid
			" . $where . "
			$where_condition
			$where_friends
			")-&gt;fetchColumn();
			
		//и выборка самих историй по такому же принципу 
		$sqllist = $db-&gt;query("SELECT f.*, u.* $join_columns 
			FROM $db_stories AS f $join_condition 
			LEFT JOIN $db_users AS u ON u.user_id=f.item_userid 
			" . $where . " 
			$where_condition
			$where_friends
			" . $order . "
			LIMIT $d, " . $maxrowsperpage); //$maxrowsperpage = 30
			
		$sqllist_rowset = $sqllist-&gt;fetchAll();
		$sqllistcount = $sqllist-&gt;rowCount();
		</pre>

<p>По сути мой вопрос в чем - если friends_ids будет сотни и тысячи значений, не станут ли запросы в БД слишко тяжелыми и как лучше поступить в такой ситуации?</p>
<p class="updated"><strong>Added 56 seconds later:</strong></p><p>собственно беспокойство вызывает <code class="php string">OR item_userid IN ("</code><code class="php plain">.implode(</code><code class="php string">','</code><code class="php plain">, </code><code class="php functions">array_map</code><code class="php plain">(</code><code class="php string">'intval'</code><code class="php plain">, </code><code class="php variable">$friends_ids</code><code class="php plain">)).</code><code class="php string">"))"</code><code class="php plain">;</code></p>
<p class="updated"><strong>Added 5 minutes later:</strong></p><p>PS<br />
индексы в БД для нужных полей есть</p>

<p>item_userid для db_stories<br />
user_id для db_users изначально есть в котонти</p>

<p class="p1">Композитный индекс для userid, friendid, status в таблице $db_cot_social_friendslist так же есть</p>

<p> </p>
]]></description>
			<pubDate>Ma, 17 Feb 2025 09:25:42 -0000</pubDate>
			<link><![CDATA[https://www.cotonti.com/nl/forums?m=posts&q=9387&d=0#post48208]]></link>
		</item>
	</channel>
</rss>