Actually, you have a third option: you can use the Execute method of the
Database itself, rather than creating a QueryDef and using its Execute
method.
I much prefer using the Execute method because it allows you to specify
dbFailOnError as an argument so that trappable error messages are generated
if there's a problem running the query. As well, it doesn't present the
annoying "You are about to append n records..." message (yes, I know you can
turn that off using SetWarnings).
So in order of preference I'd say:
1. Execute method of Database object
2. Execute method of QueryDef object
3. DoCmd.RunSQL