การสร้างการเชื่อมต่อฐานข้อมูล - ทำเพียงครั้งเดียวหรือแต่ละแบบสอบถาม


101

ในขณะนี้ฉันสร้างการเชื่อมต่อฐานข้อมูลเมื่อหน้าเว็บของฉันถูกโหลดครั้งแรก จากนั้นฉันจะประมวลผลหน้าเว็บและเรียกใช้แบบสอบถามใด ๆ กับ conection นั้น นี่เป็นวิธีที่ดีที่สุดในการทำหรือฉันควรสร้างการเชื่อมต่อฐานข้อมูลทุกครั้งที่ฉันเรียกใช้แบบสอบถามหรือไม่

ปล. ฉันรู้สึกดีกว่าที่จะสร้างการเชื่อมต่อ 1 ครั้งและใช้งานได้ แต่ฉันไม่รู้ว่าจะทำให้เกิดปัญหาอื่น ๆ หรือไม่

ฉันใช้ C # (ASP.NET) กับ MSSQL

คำตอบ:


124

หากคุณสร้างหนึ่งรายการต่อการสืบค้น / การทำธุรกรรมการจัดการ "ปิด" การเชื่อมต่อจะง่ายกว่า

ฉันสามารถดูได้ว่าทำไมสามัญสำนึกสั่งให้คุณเปิดและใช้มันตลอด แต่คุณจะพบปัญหากับการเชื่อมต่อที่ลดลงและการมัลติเธรด ดังนั้นขั้นตอนต่อไปของคุณคือการเปิดพูลพูดถึง 50 การเชื่อมต่อและทำให้พวกเขาเปิดอยู่และดึงพวกเขาออกไปสู่กระบวนการต่าง ๆ แล้วคุณจะพบว่านี่คือสิ่งที่กรอบ NET ที่ทำให้คุณมีอยู่แล้ว

หากคุณเปิดการเชื่อมต่อเมื่อคุณต้องการและกำจัดเมื่อเสร็จแล้วนั่นจะไม่ปิดการเชื่อมต่อจริง ๆ มันก็จะส่งกลับไปยังกลุ่มการเชื่อมต่อที่จะใช้อีกครั้ง


เป็นเพียงการอ่านบทความนั้นเมื่อคุณโพสต์ :) ขอบคุณ
webnoob

2
หน้าเว็บที่คุณเชื่อมโยงนั้นใช้เฉพาะกับ SQL Server . NET จัดเตรียมการรวมกำไรอัตโนมัติหรือไม่เมื่อเชื่อมต่อกับฐานข้อมูลอื่นเช่น Oracle, Sqlite, MySql
briddums

@briddums - ฉันคิดว่าขึ้นอยู่กับการเชื่อมต่อ . Net ตัวอย่างเช่นไม่มีตัวเชื่อมต่อ MySql มันเขียนและดูแลโดย MySql และในขณะที่ใช้งานได้จากประสบการณ์ของฉันการใช้งานก่อนหน้านี้ยังห่างไกลจากข้อบกพร่อง
ZweiBlumen

1
@briddums: ขึ้นอยู่กับแอสเซมบลีของผู้ให้บริการ ฉันมั่นใจว่าทั้ง Oracle ของ Microsoft และ Oracle ของทั้งสองนั้นรองรับการรวมการเชื่อมต่อเพราะฉันใช้มัน ฉันได้ยินมาว่ามี MySql อยู่แล้วและฉันคาดหวังว่าผู้ให้บริการใน Spring.NET จะสนับสนุนการรวมกำไรกัน แต่คุณดีกว่าการค้นหาหรือขอให้ผู้ให้บริการโดยตรงมากกว่าถามฉัน
pdr

1
ควรทราบว่าการเปิดการเรียกใช้แบบสอบถามและการกำจัดการเชื่อมต่อแม้ในลูปจะเร็วพอ ๆ กันและบางครั้งเร็วกว่าการเปิดเพียงครั้งเดียวแล้ววนลูปแบบสอบถาม กำจัดทิ้งเสมอ มันปลอดภัยและรวดเร็ว ไม่ต้องกังวลกับค่าใช้จ่ายในการเชื่อมต่อจากสระว่ายน้ำ - มันเป็นเรื่องเล็กน้อย
smdrager

38

วิธีปฏิบัติที่ดีที่สุดคือสร้างการเชื่อมต่อหนึ่งรายการต่อแบบสอบถาม - และในกรณีที่แสดงข้อมูลแนวปฏิบัติที่ดีที่สุดคือการให้แบบสอบถามนำข้อมูลที่จำเป็นทั้งหมดมาใช้ในครั้งเดียว

ข้อมูลพื้นฐาน:

ใน. NET การโทรSqlConnection.Open()โดยค่าเริ่มต้นจะใช้การเชื่อมต่อร่วมกันอย่างโปร่งใสเสมอ(ดู"การใช้การเชื่อมต่อรวมกับ SQL Server"บน MSDN) ดังนั้นคุณสามารถคว้าการเชื่อมต่อใหม่โดยใช้Open()และโทรClose()เมื่อคุณทำเสร็จแล้ว. NET จะทำสิ่งที่ถูกต้อง

โปรดทราบว่าหากไม่มีการรวมการเชื่อมต่อการเชื่อมต่อหนึ่งครั้งต่อการสืบค้นจะเป็นแนวคิดที่ไม่ดีมากเนื่องจากการสร้างการเชื่อมต่อฐานข้อมูลจริงอาจมีค่าใช้จ่ายสูงมาก (การตรวจสอบความถูกต้องเครือข่ายค่าโสหุ้ย ฯลฯ )


7
@webnoob - เนื่องจาก. NET ใช้การรวมการเชื่อมต่อไม่เลย เหตุผลก็คือการเชื่อมต่อสามารถปิด, จัดสรรใหม่และอื่น ๆ - ดังนั้นการใช้การเชื่อมต่อซ้ำไม่ใช่วิธีปฏิบัติที่ดี
Oded

11
-1 คำตอบค่อนข้างทำให้เข้าใจผิด การสร้างการเชื่อมต่อต่อแบบสอบถามเป็นความคิดที่แย่มาก สิ่งที่คุณอาจหมายถึงคือ "ดึงการเชื่อมต่อใหม่สำหรับแต่ละแบบสอบถามจากกลุ่มการเชื่อมต่อ" - แต่นั่นไม่เหมือนกับการสร้างการเชื่อมต่อ
sleske

1
@sleske - แตกต่างจากคำตอบของ pdr อย่างไร?
Oded

3
@Oded: อ่าฉันเข้าใจแล้ว ใน. NET การโทรSqlConnection.Open()จะใช้การรวมการเชื่อมต่ออย่างโปร่งใสเสมอ ดังนั้นความแตกต่างระหว่าง "เปิดการเชื่อมต่อ" และ "ดึงการเชื่อมต่อจากกลุ่ม" จึงไม่มีอยู่ ความเข้าใจผิดของฉัน ฉันใช้เสรีภาพในการแก้ไขคำอธิบายเล็กน้อยในคำถามและนำการโหวตกลับมา
sleske

2
@ eaglei22 - ควรทำอย่างนั้น (ดูdocs.microsoft.com/en-us/dotnet/framework/data/adonet/… ) โดยทั่วไปแล้วคุณต้องการคืนค่าการเชื่อมต่อไปยังพูลโดยเร็วที่สุดเท่าที่จะเป็นไปได้แม้ว่าคุณจะออกแบบสอบถามจำนวนมากตามลำดับอาจเป็นการดีกว่าที่จะใช้การเชื่อมต่อซ้ำตามที่คุณแนะนำ คุณจะต้องทดสอบและดูว่าวิธีใดดีกว่าสำหรับคุณ (ฉันไม่ทราบว่าคุณใช้เกณฑ์ใด - ตรวจสอบทั้งสองวิธีและดูผลกระทบที่มีต่อเมตริกที่คุณเลือก)
Oded

0

โปรดจำไว้ว่าทั้งหมดนี้อยู่ในบริบทของระบบนิเวศ. Net

นักพัฒนาบางครั้งต้องการ "เพิ่มประสิทธิภาพ" รหัสเพื่อใช้วัตถุการเชื่อมต่อของพวกเขาอีกครั้ง เมื่อพิจารณาถึงบริบทของคำถามนี้นี่เป็นความผิดพลาดเกือบทุกครั้ง

ADO.Net มีคุณสมบัติที่เรียกว่าเชื่อมต่อร่วมกัน เมื่อคุณสร้างและเปิดวัตถุเชื่อมต่อใหม่สิ่งที่คุณกำลังทำจริง ๆ คือร้องขอการเชื่อมต่อจากกลุ่ม เมื่อคุณปิดการเชื่อมต่อคุณจะกลับสู่สระ

มันเป็นสิ่งสำคัญที่จะเข้าใจวัตถุที่เราใช้โดยตรงในรหัส: SqlConnection, MySqlConnection, OleDbConnectio ฯลฯ มีทั้งหมดเพียงแค่ห่อรอบเชื่อมต่อพื้นฐานจริงจัดการโดย ADO.Net และการเชื่อมต่อจริง ADO.Net มีมาก "หนัก" และมีราคาแพงมากขึ้น จากมุมมองประสิทธิภาพ มันคือวัตถุพื้นฐานที่มีความกังวลเช่นการรับรองความถูกต้องการส่งผ่านเครือข่ายการเข้ารหัสและสิ่งเหล่านั้นมีมากกว่าหน่วยความจำในวัตถุที่คุณเห็นในรหัสของคุณ

เมื่อคุณพยายามที่จะใช้วัตถุการเชื่อมต่อของคุณใหม่คุณทำลายความสามารถในการ ADO.Net เพื่อจัดการการเชื่อมต่อพื้นฐานที่สำคัญได้อย่างมีประสิทธิภาพ คุณได้รับประสิทธิภาพในสิ่งเล็ก ๆ น้อย ๆ ด้วยค่าใช้จ่ายของสิ่งใหญ่

การใช้การเชื่อมต่อข้ามแอปพลิเคชันหรือคำขอ HTTP อีกครั้งยังสามารถบังคับให้คุณทำสิ่งที่เป็นอันดับต่อเนื่องโดยไม่ตั้งใจซึ่งอาจทำให้สามารถทำงานแบบขนานและกลายเป็นปัญหาคอขวดของประสิทธิภาพการทำงาน ฉันเคยเห็นสิ่งนี้เกิดขึ้นในแอปพลิเคชันจริง

ในกรณีตัวอย่างหน้าเว็บที่นี่อย่างน้อยที่สุดคุณเชื่อมต่อเพียงเล็กน้อยในช่วงเวลาของการร้องขอ / ตอบกลับ http เดียวคุณสามารถเพิ่มประสิทธิภาพได้มากขึ้นโดยการประเมินว่าแบบสอบถามใดที่คุณเรียกใช้ในขั้นตอนการร้องขอของคุณ พวกเขาลงไปที่คำขอที่แยกกันไปยังฐานข้อมูลน้อยที่สุดเท่าที่จะทำได้ (คำใบ้: คุณสามารถส่งแบบสอบถามมากกว่าหนึ่งรายการในสตริง SQL เดียวและใช้DataReader.NextResult()หรือตรวจสอบตารางอื่นในการDataSetย้ายระหว่างพวกเขา)

กล่าวอีกนัยหนึ่งแทนที่จะคิดในแง่ของการใช้การเชื่อมต่อหนึ่งครั้งสำหรับแอปพลิเคชันหรือการร้องขอ http เทียบกับการเชื่อมต่อหนึ่งครั้งต่อการค้นหาให้คิดในแง่ของการเชื่อมต่อหนึ่งครั้งในแต่ละครั้งที่คุณโทรออกไปยังฐานข้อมูล ... จากนั้นพยายามลดจำนวนการเชื่อมต่อโดยลดจำนวนการเดินทางเหล่านั้นให้น้อยที่สุด ด้วยวิธีนี้คุณสามารถบรรลุเป้าหมายทั้งสองได้


แต่นั่นเป็นเพียงการเพิ่มประสิทธิภาพอย่างหนึ่ง นอกจากนี้ยังมีการเพิ่มประสิทธิภาพเวลาโปรแกรมเมอร์และการใช้รหัสที่มีประสิทธิภาพอีกครั้ง นักพัฒนาไม่ต้องการที่จะเขียนรหัสต้นแบบเดียวกันซ้ำแล้วซ้ำอีกเพียงเพื่อรับวัตถุการเชื่อมต่อที่เปิดและพร้อมใช้งาน มันไม่เพียง แต่น่าเบื่อเท่านั้น แต่ยังเป็นวิธีการแนะนำข้อบกพร่องในโปรแกรมอีกด้วย

แม้ว่าที่นี่จะดีกว่าหากมีการเชื่อมต่อหนึ่งรายการต่อการสืบค้นหนึ่งรายการ (หรือไปกลับ) มีรูปแบบอื่น ๆ ที่คุณสามารถใช้เพื่อช่วยหลีกเลี่ยงการเขียนรหัสสำเร็จรูปแผ่นเดียวกันอีกครั้ง นี่คือตัวอย่างหนึ่งที่ฉันชอบ แต่ก็มีอีกหลายอย่าง


ฉันสายไปงานเลี้ยงนี้ แต่ฉันคิดว่าคำตอบนี้ครอบคลุมบางจุดที่สำคัญ :)
โจเอล Coehoorn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.