از نظر سرعت چه فرقی بین Repo.all و Repo.one وجود دارد ؟

با درود خدمت شما . از اونجایی که هدف بنده به شخصه این هست که تمام سوالاتم در زمینه الکسیر رو به این انجمن اضافه کنم تا کمی منابع فارسی در این زمینه قوی بشه به همین منظور یکی از سوالات خودم که قبلا در انجمن سازنده الکسیر پرسیدم رو هم اینجا می زارم که اگر بحثی هم در پیرو آن شد که چه بهتر .

لینک پست :


برای من سوال بود که بین دو کد زیر چه فرقی وجود دارد :
defp fetch_posts_by_alias(post_alias, "admin") do
		query = from p in Post,
						 join: c in assoc(p, :cms_post_category),
						 where: p.seo_alias_link == ^post_alias,
						 order_by: p.inserted_at

		query = admin_fields(query)
		Repo.one(query)
	end 

و بین کد زیر :

	defp fetch_posts_by_alias(post_alias, "admin") do
		query = from p in Post,
						 join: c in assoc(p, :cms_post_category),
						 where: p.seo_alias_link == ^post_alias,
						 order_by: p.inserted_at

		query = admin_fields(query)
		Repo.all(query)
	end

در صورتی که هر دو یک نتیجه را برگشت می دهند به همین منظور یک پست زدم که آیا از نظر سرعت فرقی بین آن ها وجود دارد ؟

حال برای بنده پاسخ هایی ارسال شد که این نظر که از سرعت در این وسط پارامتر هست یا نه ؟ که بر اساس نظرات ارسالی متوجه این موضوع شدم که بحث بحث سرعت نیست بلکه خروجی پایانی یا گارانتی می باشد

این هم لینک در سورس الکسیر می باشد

Repo.all همه داده رو برمیگردونه
Repo.one فقط یک رکورد

1 پسندیده

سام عزیز در این مورد مشکلی نیست ولی شما توجه کنید به دو قطعه کد یکی با where توی repo.all اومده همون یک ریزولت رو گرفته . بیشتر نظرم بر این موضوع بود که در این دو قعطه کد چه فرقی دارند ؟

هر دو یک کارو انجام می دهند یعنی خروجی که کاربر می بیند یک چیز هست

نه عرض کردم اینا باهم فرق میکنن اگر جدول ۱۰ رکورد داشته باشه all همه رو برمیگردونه one فقط یک رکورد

1 پسندیده

آها یعنی all اول کل جدول می گرده بعد پاسخ رو می ده ولی one به اولین جواب درست رسید دیگه ما بقی رو نمی گرده , درسته صحبت بنده ؟

بله تو sql به limit نگاه کن
One در واقع limit 1 داره all هیچ limit نداره

1 پسندیده

خیلی لطف کردید سام عزیز ممنون از راهنماییت .

یک سوالی هم دارم که اگر زمان داشتید پاسخ بدید ممنون می شم . اینجوری که مشخصه و در یک جایی هم دیشب خوندم فکر کنم . در کل Ecto چیزی به نام lazy loading نداره درسته ؟ یعنی تا آخرین جرعه از رم می کشه بیرون , درسته ؟

نه ecto در حالت معمولی lazy loading میکنه
Repository pattern ساختار داده entity از query جدا میکنه در ecto تمام قسمت های ساخت query
Lazy هستند
یعنی

query = from u in "users",
          where: u.age > 18,
          select: u.name

این هیچ کاری نمیکنه و lazy هست تا وقتی به Repo.all داده بشه به همین دلیل preload استفاده میکنی بعضی وقتها برای جدول های مرتبط اجباری lazy نباشه و eager داده رو بیاره که n+1 نگیری

1 پسندیده

سام عزیز آیا جایگاه فیلتر ها در یک کوآری نیز تاثیر بر این موضوع داره ؟

به عنوان مثال اول order بیاد بعد where بیاد یا اول limit بیاد بعد بقیه بیاند

query = from u in "cms_post_category",
					where: u.group_acl in ^group_acl,
					order_by: u.inserted_at,

اگر این ترتیب در کوآری تاثیر داره آیا استاندارد خاصی براش وجود داره ؟

ترتیب ،اثر نداره ecto تمام query تبدیل میکنه به query sql

1 پسندیده

سام عزیز من با لینک هایی که دیروز توماج عزیز هم دارد در مورد n+1 اینا مطالعه کردم . برام یک سوال در عمل پیش اومده . ما وقتی می یاییم بر اساس صحبت شما preload استفاده می کنیم این کارو می کنیم که دیگه lazy نباشه . خوب این فرقش با select تمام فیلد های دو تیبل چیست ؟

آیا اون هم از حالت lazy در اومده یا خیر ؟ وقتی تمام فیلد های دو جدول کامل ریلیشن شده داره فراخوانی می شه ؟

اگر بله باشه صحبت شما پس پریلود در این زمان یا جایی که به هر صورت داریم تمام فیلد هارو می خونیم فقط سادگی فراخوانی رو برای ما تامین می کنه , آیا صحبت من درسته یا اشتباه ؟

ممنون سام عزیز که این بحث هارو جلو می برید و زمان می زارید بنده خیلی دارم استفاده می کنم و با هر صحبت شما تقریبا خیلی از کد هامو ویرایش می کنم. ممنونم

بهترین راه اینکه شما یک query با preload بنویسی و همونو بدون preload بعد نگاه کن به تفاوت طوری که ecto
Query میکنه دیتابیس رو
شنیدن کی بود مانند دیدن

1 پسندیده

من این کارو انجام دادم سام عزیز ولی تفاوت خاصی ندیدم . هم داده های من در دیتابیس بسیار کمه و هم اینکه انگار چندبار پشت سر هم می زنم یک درخواستی رو در سایت متوجه این می شم که هر دفعه زمان پاسخگوییش کمتر می شه .

حتی یک بار دیدم مثلا یکی ۳ میلی ثانیه سریع تر بود ولی بعدا دیدم دو میلی ثانیه حتی دیر کرد داشت.
فکر کنم این مورد باید در سرویسی که بعدا به صورت کامل بالا اومد بیاد بالا و دو فانکشن تست بشه

با ریلز یک کم کارکنی n+1 با پوست و استخوان درک میکنی :smile:
لاگ Phoenix نگاه کن query متفاوته

1 پسندیده

فونیکس مگه لاگ داره :thinking: من فقط چیزی تو ترمینال چاپ می شه رو همیشه نگاه می کنم و با اون زمانی که نرم افزاری که درخواست می ده به سرور تا جواب بگیره :pensive: یعنی لاگ داشته تا حالا من نمی دونستم

یعنی انقدر پردازشش بده :grin:

چیزی که تو ترمینال میبینی لاگ میشه همون تو ترمینال ببینی query فرق میکنه به پردازش ریلز مربوط نیست به طوری که activerecord ساخته شده آسونه خیلی n+1 بگیری

1 پسندیده

بنده همونجا رو دقیقا می گم

همین زمانی که نوشته مثلا db=5.7 یا زمانی که در آخر می نویسه یا زمانی که برای queue زده می شه .

من اینارو برای پریلود و همینطور برای join خالی تست کردم و همونی شد که بالا خدمت شما گفتم

Query نگاه کن سرعت بحث نیست

1 پسندیده

شرمنده دارم وقتتون می گیرم ولی هنوز متوجه نشدم دقیقا Query شما می گید لاگ می شه دقیقا کجا مثلا این تصویرم هست کل کوآری که داره لاگ می شه تو ترمینالم اینه

[debug] QUERY OK source="cms_post_category" db=5.7ms queue=0.1ms
SELECT c0."title", c0."status", c0."language", c0."group_acl", c0."description", c0."seo_alias_link", c0."seo_words", c0."seo_description", c0."seo_language", c0."seo_language_link", c0."pic_x1_link", c0."pic_x2_link", c0."pic_x3_link" FROM "cms_post_category" AS c0 WHERE (c0."group_acl" = ANY($1)) ORDER BY c0."inserted_at" [["unactived", "", "actived"]]

اینو میگم بله میگم یک بار preload بگذار ببین و یک بار بدون preload