In a first home fixture since November's win over Denmark, O'Neill's side continued their good recent form in front of a packed Windsor Park.
Led out by 22-year-old Sunderland defender Trai Hume, who was captaining his country for the first time after the international retirement of Jonny Evans, the hosts made a bright start as the sun set in a crisp and cool Belfast.
Forwards Callum Marshall and Dion Charles spurned half chances, both of which came from set plays, before McNair finally punished Luxembourg for failing to deal with deliveries into the box.
Ciaron Brown launched a long throw into the area, which the visitors failed to clear and McNair kept his cool to take a touch and poke the ball into the bottom corner.
A good start swiftly became a great one when Sunderland defender Ballard made it two in the 17th minute after Conor Bradley was fouled just outside the penalty area.
Just like he did against Spain in June, Ballard got himself on the scoresheet from a free-kick when he got in front of his marker to flick home Saville's low free-kick.
After a lull in the action, Bradley almost grabbed a superb solo goal at the end of the half but Christopher Martins put in a strong clearance to deny the Liverpool defender.
Captain Hume went even closer when Luxembourg only cleared to the edge of the area and the Sunderland man curled an effort off the outside of the post.
Luxembourg's only meaningful attack came in additional time when Leandro Barreiro poked over the bar as he raced on to a long ball.