การเปลี่ยนแปลงแบบแผน
- ดึงข้อมูลตามคำสั่ง --- หากรหัสกำลังดึงข้อมูลคอลัมน์ # เป็นวิธีรับข้อมูลการเปลี่ยนแปลงในสคีมาจะทำให้หมายเลขคอลัมน์ปรับใหม่ สิ่งนี้จะทำให้แอปพลิเคชั่นยุ่งเหยิงและสิ่งเลวร้ายจะเกิดขึ้น
- การดึงข้อมูลตามชื่อ --- หากรหัสกำลังดึงข้อมูลคอลัมน์ตามชื่อเช่น
foo
และตารางอื่นในแบบสอบถามเพิ่มคอลัมน์foo
วิธีการจัดการนี้อาจทำให้เกิดปัญหาเมื่อพยายามรับคอลัมน์ที่ถูกต้อง foo
ไม่ว่าจะด้วยวิธีใดการเปลี่ยนแปลงสคีมาอาจทำให้เกิดปัญหากับการแยกข้อมูล
พิจารณาเพิ่มเติมว่าคอลัมน์ที่ใช้ถูกลบออกจากตาราง select * from ...
ยังคงทำงาน แต่ข้อผิดพลาดออกมาเมื่อพยายามที่จะดึงข้อมูลออกจากผลการตั้งค่า หากมีการระบุคอลัมน์ในแบบสอบถามการสืบค้นจะเกิดข้อผิดพลาดแทนที่จะให้การบ่งชี้ที่ชัดเจนว่าอะไรและปัญหานั้นอยู่ที่ไหน
ข้อมูลค่าใช้จ่าย
บางคอลัมน์สามารถมีข้อมูลจำนวนมากที่เกี่ยวข้อง เลือกกลับ*
จะดึงทุกข้อมูล ใช่นี่คือจำนวนvarchar(4096)
1,000 แถวที่คุณเลือกกลับมาให้ข้อมูลเพิ่มเติมที่เป็นไปได้ 4 เมกะไบต์ที่คุณไม่ต้องการ แต่จะถูกส่งข้ามสาย
เกี่ยวข้องกับการเปลี่ยนแปลงสกีมา varchar นั้นอาจไม่มีอยู่เมื่อคุณสร้างตารางครั้งแรก แต่ตอนนี้มีอยู่ที่นั่น
ความล้มเหลวในการถ่ายทอดเจตนา
เมื่อคุณเลือกกลับมา*
และรับ 20 คอลัมน์ แต่ต้องการเพียง 2 คอลัมน์คุณไม่ได้ถ่ายทอดเจตนาของรหัส เมื่อดูที่การค้นหาที่select *
ไม่ทราบว่าส่วนสำคัญของมันคืออะไร ฉันสามารถเปลี่ยนคิวรีเพื่อใช้แผนอื่นแทนเพื่อทำให้เร็วขึ้นโดยไม่รวมคอลัมน์เหล่านี้ได้หรือไม่ ฉันไม่รู้เพราะเจตนาของสิ่งที่แบบสอบถามส่งคืนไม่ชัดเจน
ให้ดูที่ SQL fiddles ที่สำรวจschemaเหล่านั้นเปลี่ยนแปลงไปอีกเล็กน้อย
ก่อนอื่นฐานข้อมูลเริ่มต้น: http://sqlfiddle.com/#!2/a67dd/1
DDL:
create table one (oneid int, data int, twoid int);
create table two (twoid int, other int);
insert into one values (1, 42, 2);
insert into two values (2, 43);
SQL:
select * from one join two on (one.twoid = two.twoid);
และคอลัมน์ที่คุณได้รับกลับมามีoneid=1
, data=42
, และtwoid=2
other=43
ตอนนี้จะเกิดอะไรขึ้นถ้าฉันเพิ่มคอลัมน์ลงในตารางที่หนึ่ง http://sqlfiddle.com/#!2/cd0b0/1
alter table one add column other text;
update one set other = 'foo';
และผลของฉันจากแบบสอบถามเช่นเดียวกับก่อนมีoneid=1
, data=42
, และtwoid=2
other=foo
การเปลี่ยนแปลงในตารางใดตารางหนึ่งจะกระทบกับค่าของ a select *
และในทันทีที่การเชื่อมโยงของคุณกับ 'อื่น ๆ ' กับ int กำลังจะเกิดข้อผิดพลาดและคุณไม่รู้ว่าทำไม
ถ้าแทนคำสั่ง SQL ของคุณคือ
select
one.oneid, one.data, two.twoid, two.other
from one join two on (one.twoid = two.twoid);
การเปลี่ยนแปลงในตารางที่หนึ่งจะไม่ทำให้ข้อมูลของคุณหยุดชะงัก แบบสอบถามนั้นจะทำงานเหมือนเดิมก่อนการเปลี่ยนแปลงและหลังการเปลี่ยนแปลง
การจัดทำดัชนี
เมื่อคุณทำselect * from
คุณจะดึงทุกแถวในรูปแบบทุกตารางที่ตรงกับเงื่อนไขที่ แม้กระทั่งตารางที่คุณไม่สนใจจริงๆ ขณะนี้หมายความว่ามีการถ่ายโอนข้อมูลมากขึ้น แต่ยังมีปัญหาเรื่องประสิทธิภาพอื่น ๆ
ดัชนี (สัมพันธ์กับ SO: วิธีการใช้ดัชนีในคำสั่ง select? )
หากคุณดึงคอลัมน์จำนวนมากออกมาเครื่องมือเพิ่มประสิทธิภาพแผนฐานข้อมูลอาจไม่สนใจการใช้ดัชนีเนื่องจากคุณยังคงต้องดึงข้อมูลคอลัมน์เหล่านั้นทั้งหมดต่อไปและจะใช้เวลามากขึ้นในการใช้ดัชนีแล้วดึงข้อมูลคอลัมน์ทั้งหมดในแบบสอบถาม กว่าจะเป็นเพียงการสแกนตารางที่สมบูรณ์
หากคุณเป็นเพียงการเลือกพูดนามสกุลของผู้ใช้ (ซึ่งคุณทำมากและเพื่อให้มีดัชนีในนั้น), ฐานข้อมูลสามารถทำดัชนีเพียงสแกน ( ดัชนี postgres วิกิพีเดียเท่านั้นสแกน , MySQL ตารางการสแกน VS เต็ม การสแกนดัชนี , การสแกนดัชนีเท่านั้น: หลีกเลี่ยงการเข้าถึงตาราง )
มีการเพิ่มประสิทธิภาพค่อนข้างน้อยเกี่ยวกับการอ่านจากดัชนีเท่านั้นถ้าเป็นไปได้ เป็นข้อมูลที่สามารถดึงได้เร็วขึ้นในหน้าดัชนีแต่ละเพราะคุณกำลังดึงน้อยของมันยัง - คุณไม่ได้ในการดึงทุกคนที่คอลัมน์อื่น ๆ select *
สำหรับ เป็นไปได้สำหรับดัชนีสแกนเท่านั้นที่จะส่งคืนผลลัพธ์ตามลำดับ 100x เร็วขึ้น (ที่มา: เลือก * ไม่ดี )
นี่ไม่ได้บอกว่าการสแกนดัชนีแบบสมบูรณ์นั้นยอดเยี่ยม แต่ก็ยังเป็นการสแกนแบบสมบูรณ์ แต่ดีกว่าการสแกนแบบเต็มตาราง เมื่อคุณเริ่มไล่ตามทุกวิธีที่select *
ทำร้ายประสิทธิภาพการทำงานคุณจะต้องหาวิธีใหม่ ๆ
การอ่านที่เกี่ยวข้อง